How to programmatically manipulate DLGTEMPLATE?

What?

I have a DLGTEMPLATE loaded from a resource DLL, how can I change the lines assigned to controls at runtime programmatically?

I want to be able to do this before creating a dialog so that I can say that the lines displayed on the screen come from the resource DLL, and not from the SetWindowText calls when the dialog is initialized.

Google has found examples of creating DLGTEMPLATEs in code or crossing simple style bits, but nothing edits the lines in memory.

How?

I do this by connecting the dialog box Create Property / Property Sheet API. This gives me access to DLGTEMPLATE before creating the actual dialog and before it has HWND.

Why?

I want to be able to perform localization at runtime and testing localization. I have already implemented this for loading a string (including the MFC 7.0 shell), menus and accelerator tables, but I'm trying my best to handle creating a dialog box / property.

Code examples would be the perfect answer, ideally a class for wrapping around DLGTEMPLATE, if I develop my own solution, I will publish it.

+3
source share
5 answers

You cannot edit lines in memory. The DLGTEMPLATE structure is a direct file mapping of the corresponding bytes of the dll resource. This is a read only.

You will need to process the entire DLGTEMPLATE structure and write a new one with modified length strings.

WM_INITDIALOG , , DLGTEMPLATE. . .res( .dll inplace), Id .

, accellerator - , , DLGTEMPLATE , .

+5

- (, , Microsoft, ), RESFMT.ZIP, . . , DIALOGEX DIALOG .

, . , . , .

, WORD * lpIn. . DIALOG (. DLGTEMPLATE), , MSDN.

, : , DIALOG, . .

( -, , RESFMT.ZIP):

WORD *AlignDwordPtr (WORD *lpIn)
    {
    ULONG ul;

    ul = (ULONG) lpIn;
    ul +=3;
    ul >>=2;
    ul 

What I did was build a series of functions like this one following that allowed me to assemble DIALOGS in memory. (My need was so I could have some common code that didn't need an associated RC file for some very basic messages).

Here is an example...

WORD *AddStringOrOrdinalToWordMem( WORD *lpw, char    *sz_Or_Ord )
    {
    LPWSTR  lpwsz;
    int     BufferSize;

    if (sz_Or_Ord == NULL)
        {
        *lpw++ = 0;
        }
    else
        {
        if (HIWORD(sz_Or_Ord) == 0) //MAKEINTRESOURCE macro 
            {
            *lpw++ = 0xFFFF;
            *lpw++ = LOWORD(sz_Or_Ord);
            }
        else
            {
            if (strlen(sz_Or_Ord))
                {
                lpwsz = ( LPWSTR ) lpw;
                BufferSize = MultiByteToWideChar( CP_ACP, 0, sz_Or_Ord, -1, lpwsz, 0 );
                MultiByteToWideChar( CP_ACP, 0, sz_Or_Ord, -1, lpwsz, BufferSize );
                lpw = lpw +  BufferSize;
                }
            else
                {
                *lpw++ = 0;
                }
            }
        }
    return( lpw );
    }

The header file to the complete module included these functions:

WORD *AddControlToDialogTemplateEx(MTDialogTemplateType *dlgtmp, char *Title, WORD Id, char *WinClass, DWORD Style, short x, short y, short cx, short cy, DWORD ExStyle, int HelpID); int DestroyDlgTemplateEx(MTDialogTemplateType *dlgtmp); MTDialogTemplateType *CreateDlgTemplateEx( char *Name, // We use name just for reference, so it can be NULL short x, short y, short cx, short cy, DWORD ExtendedStyle, DWORD Style, char *Menu, char *WinClass, char *Caption, char *FontTypeFace, int FontSize, int FontWeigth, int FontItalic, int Charset, int HelpID, int NumberOfControls);

.

+4

API:: EnumChildWindows (HWND, WNDENUMPROC, LPARAM)

CFormView:: Create CDialog:: OnInitDialog, . , , .

- . /clr, . . /clr , Windows ( ), System:: Threading:: Thread:: CurrentThread- > CurrentUICulture.

-

CMyDialog::OnInitDialog()
{
    ::EnumChildWindows(
        this->GetSafeHwnd(),
        CMyDialog::UpdateControlText,
        (LPARAM)this )
}

BOOL CALLBACK CMyDialog::UpdateControlText( HWND hWnd, LPARAM lParam )
{
    CMyDialog* pDialog = (CMyDialog*)lParam;
    CWnd* pChildWnd = CWnd::FromHandle( hWnd );

    int ctrlId = pChildWnd->GetDlgCtrlID();
    if (ctrlId)
    {
        CString curWindowText;
        pChildWnd->GetWindowText( curWindowText );
        if (!curWindowText.IsEmpty())
        {
            CString newWindowText = // some look up
            pChildWnd->SetWindowText( newWindowText );
        }
    }
}
+1

, , mem-, . - . . , , . , .

, WM_INITDIALOG , , SetWindowText().

+1

, 24- , Windows WM_INITDIALOG, , , API, 2 .

.

0
source

Source: https://habr.com/ru/post/1698295/


All Articles