⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialog.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    info.offset = 0;
    info.length = lstrlenA( info.string ) + 1;

    es.dwCookie = (DWORD_PTR) &info;
    es.dwError = 0;
    es.pfnCallback = msi_richedit_stream_in;

    SendMessageW( control->hwnd, EM_STREAMIN, SF_RTF, (LPARAM) &es );

    msi_free( info.string );
}

static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec )
{
    static const WCHAR szRichEdit20W[] = {
    	'R','i','c','h','E','d','i','t','2','0','W',0
    };
    struct msi_scrolltext_info *info;
    msi_control *control;
    HMODULE hRichedit;
    LPCWSTR text;
    DWORD style;

    info = msi_alloc( sizeof *info );
    if (!info)
        return ERROR_FUNCTION_FAILED;

    hRichedit = LoadLibraryA("riched20");

    style = WS_BORDER | ES_MULTILINE | WS_VSCROLL |
            ES_READONLY | ES_AUTOVSCROLL | WS_TABSTOP;
    control = msi_dialog_add_control( dialog, rec, szRichEdit20W, style );
    if (!control)
    {
        FreeLibrary( hRichedit );
        msi_free( info );
        return ERROR_FUNCTION_FAILED;
    }

    control->hDll = hRichedit;

    info->dialog = dialog;
    info->control = control;

    /* subclass the static control */
    info->oldproc = (WNDPROC) SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC,
                                          (LONG_PTR)MSIScrollText_WndProc );
    SetPropW( control->hwnd, szButtonData, info );

    /* add the text into the richedit */
    text = MSI_RecordGetString( rec, 10 );
    if (text)
        msi_scrolltext_add_text( control, text );

    return ERROR_SUCCESS;
}

static HBITMAP msi_load_picture( MSIDATABASE *db, LPCWSTR name,
                                 INT cx, INT cy, DWORD flags )
{
    HBITMAP hOleBitmap = 0, hBitmap = 0, hOldSrcBitmap, hOldDestBitmap;
    MSIRECORD *rec = NULL;
    IStream *stm = NULL;
    IPicture *pic = NULL;
    HDC srcdc, destdc;
    BITMAP bm;
    UINT r;

    rec = msi_get_binary_record( db, name );
    if( !rec )
        goto end;

    r = MSI_RecordGetIStream( rec, 2, &stm );
    msiobj_release( &rec->hdr );
    if( r != ERROR_SUCCESS )
        goto end;

    r = OleLoadPicture( stm, 0, TRUE, &IID_IPicture, (LPVOID*) &pic );
    IStream_Release( stm );
    if( FAILED( r ) )
    {
        ERR("failed to load picture\n");
        goto end;
    }

    r = IPicture_get_Handle( pic, (OLE_HANDLE*) &hOleBitmap );
    if( FAILED( r ) )
    {
        ERR("failed to get bitmap handle\n");
        goto end;
    }
 
    /* make the bitmap the desired size */
    r = GetObjectW( hOleBitmap, sizeof bm, &bm );
    if (r != sizeof bm )
    {
        ERR("failed to get bitmap size\n");
        goto end;
    }

    if (flags & LR_DEFAULTSIZE)
    {
        cx = bm.bmWidth;
        cy = bm.bmHeight;
    }

    srcdc = CreateCompatibleDC( NULL );
    hOldSrcBitmap = SelectObject( srcdc, hOleBitmap );
    destdc = CreateCompatibleDC( NULL );
    hBitmap = CreateCompatibleBitmap( srcdc, cx, cy );
    hOldDestBitmap = SelectObject( destdc, hBitmap );
    StretchBlt( destdc, 0, 0, cx, cy,
                srcdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
    SelectObject( srcdc, hOldSrcBitmap );
    SelectObject( destdc, hOldDestBitmap );
    DeleteDC( srcdc );
    DeleteDC( destdc );

end:
    if ( pic )
        IPicture_Release( pic );
    return hBitmap;
}

static UINT msi_dialog_bitmap_control( msi_dialog *dialog, MSIRECORD *rec )
{
    UINT cx, cy, flags, style, attributes;
    msi_control *control;
    LPWSTR text;

    flags = LR_LOADFROMFILE;
    style = SS_BITMAP | SS_LEFT | WS_GROUP;

    attributes = MSI_RecordGetInteger( rec, 8 );
    if( attributes & msidbControlAttributesFixedSize )
    {
        flags |= LR_DEFAULTSIZE;
        style |= SS_CENTERIMAGE;
    }

    control = msi_dialog_add_control( dialog, rec, szStatic, style );
    cx = MSI_RecordGetInteger( rec, 6 );
    cy = MSI_RecordGetInteger( rec, 7 );
    cx = msi_dialog_scale_unit( dialog, cx );
    cy = msi_dialog_scale_unit( dialog, cy );

    text = msi_get_deformatted_field( dialog->package, rec, 10 );
    control->hBitmap = msi_load_picture( dialog->package->db, text, cx, cy, flags );
    if( control->hBitmap )
        SendMessageW( control->hwnd, STM_SETIMAGE,
                      IMAGE_BITMAP, (LPARAM) control->hBitmap );
    else
        ERR("Failed to load bitmap %s\n", debugstr_w(text));

    msi_free( text );
    
    return ERROR_SUCCESS;
}

static UINT msi_dialog_icon_control( msi_dialog *dialog, MSIRECORD *rec )
{
    msi_control *control;
    DWORD attributes;
    LPWSTR text;

    TRACE("\n");

    control = msi_dialog_add_control( dialog, rec, szStatic,
                            SS_ICON | SS_CENTERIMAGE | WS_GROUP );
            
    attributes = MSI_RecordGetInteger( rec, 8 );
    text = msi_get_deformatted_field( dialog->package, rec, 10 );
    control->hIcon = msi_load_icon( dialog->package->db, text, attributes );
    if( control->hIcon )
        SendMessageW( control->hwnd, STM_SETICON, (WPARAM) control->hIcon, 0 );
    else
        ERR("Failed to load bitmap %s\n", debugstr_w(text));
    msi_free( text );
    return ERROR_SUCCESS;
}

static UINT msi_dialog_combo_control( msi_dialog *dialog, MSIRECORD *rec )
{
    static const WCHAR szCombo[] = { 'C','O','M','B','O','B','O','X',0 };

    msi_dialog_add_control( dialog, rec, szCombo,
                            SS_BITMAP | SS_LEFT | SS_CENTERIMAGE );
    return ERROR_SUCCESS;
}

static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
{
    msi_control *control;
    LPCWSTR prop;
    LPWSTR val;

    control = msi_dialog_add_control( dialog, rec, szEdit,
                                      WS_BORDER | WS_TABSTOP );
    control->handler = msi_dialog_edit_handler;
    prop = MSI_RecordGetString( rec, 9 );
    if( prop )
        control->property = strdupW( prop );
    val = msi_dup_property( dialog->package, control->property );
    SetWindowTextW( control->hwnd, val );
    msi_free( val );
    return ERROR_SUCCESS;
}

/******************** Masked Edit ********************************************/

#define MASK_MAX_GROUPS 20

struct msi_mask_group
{
    UINT len;
    UINT ofs;
    WCHAR type;
    HWND hwnd;
};

struct msi_maskedit_info
{
    msi_dialog *dialog;
    WNDPROC oldproc;
    HWND hwnd;
    LPWSTR prop;
    UINT num_chars;
    UINT num_groups;
    struct msi_mask_group group[MASK_MAX_GROUPS];
};

static BOOL msi_mask_editable( WCHAR type )
{
    switch (type)
    {
    case '%':
    case '#':
    case '&':
    case '`':
    case '?':
    case '^':
        return TRUE;
    }
    return FALSE;
}

static void msi_mask_control_change( struct msi_maskedit_info *info )
{
    LPWSTR val;
    UINT i, n, r;

    val = msi_alloc( (info->num_chars+1)*sizeof(WCHAR) );
    for( i=0, n=0; i<info->num_groups; i++ )
    {
        if( (info->group[i].len + n) > info->num_chars )
        {
            ERR("can't fit control %d text into template\n",i);
            break;
        }
        if (!msi_mask_editable(info->group[i].type))
        {
            for(r=0; r<info->group[i].len; r++)
                val[n+r] = info->group[i].type;
            val[n+r] = 0;
        }
        else
        {
            r = GetWindowTextW( info->group[i].hwnd, &val[n], info->group[i].len+1 );
            if( r != info->group[i].len )
                break;
        }
        n += r;
    }

    TRACE("%d/%d controls were good\n", i, info->num_groups);

    if( i == info->num_groups )
    {
        TRACE("Set property %s to %s\n",
              debugstr_w(info->prop), debugstr_w(val) );
        CharUpperBuffW( val, info->num_chars );
        MSI_SetPropertyW( info->dialog->package, info->prop, val );
        msi_dialog_evaluate_control_conditions( info->dialog );
    }
    msi_free( val );
}

/* now move to the next control if necessary */
static VOID msi_mask_next_control( struct msi_maskedit_info *info, HWND hWnd )
{
    HWND hWndNext;
    UINT len, i;

    for( i=0; i<info->num_groups; i++ )
        if( info->group[i].hwnd == hWnd )
            break;

    /* don't move from the last control */
    if( i >= (info->num_groups-1) )
        return;

    len = SendMessageW( hWnd, WM_GETTEXTLENGTH, 0, 0 );
    if( len < info->group[i].len )
        return;

    hWndNext = GetNextDlgTabItem( GetParent( hWnd ), hWnd, FALSE );
    SetFocus( hWndNext );
}

static LRESULT WINAPI
MSIMaskedEdit_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    struct msi_maskedit_info *info;
    HRESULT r;

    TRACE("%p %04x %08x %08lx\n", hWnd, msg, wParam, lParam);

    info = GetPropW(hWnd, szButtonData);

    r = CallWindowProcW(info->oldproc, hWnd, msg, wParam, lParam);

    switch( msg )
    {
    case WM_COMMAND:
        if (HIWORD(wParam) == EN_CHANGE)
        {
            msi_mask_control_change( info );
            msi_mask_next_control( info, (HWND) lParam );
        }
        break;
    case WM_NCDESTROY:
        msi_free( info->prop );
        msi_free( info );
        RemovePropW( hWnd, szButtonData );
        break;
    }

    return r;
}

/* fish the various bits of the property out and put them in the control */
static void
msi_maskedit_set_text( struct msi_maskedit_info *info, LPCWSTR text )
{
    LPCWSTR p;
    UINT i;

    p = text;
    for( i = 0; i < info->num_groups; i++ )
    {
        if( info->group[i].len < lstrlenW( p ) )
        {
            LPWSTR chunk = strdupW( p );
            chunk[ info->group[i].len ] = 0;
            SetWindowTextW( info->group[i].hwnd, chunk );
            msi_free( chunk );
        }
        else
        {
            SetWindowTextW( info->group[i].hwnd, p );
            break;
        }
        p += info->group[i].len;
    }
}

static struct msi_maskedit_info * msi_dialog_parse_groups( LPCWSTR mask )
{
    struct msi_maskedit_info * info = NULL;
    int i = 0, n = 0, total = 0;
    LPCWSTR p;

    TRACE("masked control, template %s\n", debugstr_w(mask));

    if( !mask )
        return info;

    info = msi_alloc_zero( sizeof *info );
    if( !info )
        return info;

    p = strchrW(mask, '<');
    if( p )
        p++;
    else
        p = mask;

    for( i=0; i<MASK_MAX_GROUPS; i++ )
    {
        /* stop at the end of the string */
        if( p[0] == 0 || p[0] == '>' )
            break;

        /* count the number of the same identifier */
        for( n=0; p[n] == p[0]; n++ )
            ;
        info->group[i].ofs = total;
        info->group[i].type = p[0];
        if( p[n] == '=' )
        {
            n++;
            total++; /* an extra not part of the group */
        }
        info->group[i].len = n;
        total += n;
        p += n;
    }

    TRACE("%d characters in %d groups\n", total, i );
    if( i == MASK_MAX_GROUPS )
        ERR("too many groups in PIDTemplate %s\n", debugstr_w(mask));

    info->num_chars = total;
    info->num_groups = i;

    return info;
}

static void
msi_maskedit_create_children( struct msi_maskedit_info *info, LPCWSTR font )
{
    DWORD width, height, style, wx, ww;
    RECT rect;
    HWND hwnd;
    UINT i;

    style = WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL;

    GetClientRect( info->hwnd, &rect );

    width = rect.right - rect.left;
    height = rect.bottom - rect.top;

    for( i = 0; i < info->num_groups; i++ )
    {
        if (!msi_mask_editable( info->group[i].type ))
            continue;
        wx = (info->group[i].ofs * width) / info->num_chars;
        ww = (info->group[i].len * width) / info->num_chars;

        hwnd = CreateWindowW( szEdit, NULL, style, wx, 0, ww, height,
                              info->hwnd, NULL, NULL, NULL );
        if( !hwnd )
        {
            ERR("failed to create mask edit sub window\n");
            break;
        }

        SendMessageW( hwnd, EM_LIMITTEXT, info->group[i].len, 0 );

        msi_dialog_set_font( info->dialog, hwnd,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -