About DLGINIT in WTL
I’m using the wizard to load some static strings into a CComboBox.
When I run the app the strings aren’t visible.
Here’s what the link below says:
Initializing a Combo-Box
The ResourceView in VC++’s DevStudio allows entries in a combobox to be
added to the resource template at design time. When you add a combobox, and
bring up its properties page, then the “Data” tab is used to add entries.
When you run an MFC app and display dialogs with combo-boxes who have had
such entries defined, they are displayed with the combo-boxes populated as
expected. With WTL, the combo-boxes get displayed, but are empty. What is
happening?
Information about the combobox (such as its control id and location on the
dialog, but excluding its data entries) is stored as part of a resource, of
type DIALOG, in the resource file. The Win32 dialog APIs understand this and
load it directly before rendering the dialog. The information about the
entries in a combobox is stored as a separate resource, of type DLGINIT. The
Win32 dialog APIs do not understand DLGINIT. Other code in higher-level
libraries or the application itself has to process DLGINIT resources.
MFC provides functionality as part of its dialog classes to cater for
DLGINIT. WTL does not. The Clipcode Reuse Library contains a WTL-friendly
function called RUiDlgInit, which loads the DLGINIT data. It is modeled on
the equivalent MFC functionality.
RUiDlgInit(IDD, m_hWnd);
You need to pass it in the IDD of the dialog and the HWND of the existing
dialog window. Typically it is called from OnInitDialog. RUiDlgInit just
runs through the fields in the DLGINIT and sends a CB_ADDSTRING to the
combo-box for each entry.
Igor, data you add to the combo box in the resource editor is stored
in the DLGINIT section of the resource script. MFC does populate the
combo box from the DLGINIT resource but clipcode ported the code to
WTL. It’s in the “FirstCalc” sample from clipcode WTL devguide.
The function is called RUiDlgInit(int nResourceID, HWND m_hWnd). You
pass it the ID of the dialog and the dialog’s hwnd.
void RUiDlgInit(int nResourceID, HWND m_hWnd)
{
HINSTANCE hInstance = _Module.GetResourceInstance();
HRSRC hResource = ::FindResource(hInstance, MAKEINTRESOURCE
(nResourceID), RT_DLGINIT);
// If not DLGINIT, that's not an error
if (hResource == NULL)
return;
HGLOBAL hGlobal = ::LoadResource(hInstance, hResource);
if (hGlobal == NULL)
return;
LPVOID lpResource = ::LockResource(hGlobal);
if (lpResource == NULL)
return;
BOOL bSuccess = TRUE;
// Now walk the loaded resource
UNALIGNED WORD* lpnRes = (WORD*)lpResource;
while (bSuccess && *lpnRes != 0)
{
WORD nIDC = *lpnRes++;
WORD nMsg = *lpnRes++;
DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;
#define WIN16_LB_ADDSTRING 0x0401
#define WIN16_CB_ADDSTRING 0x0403
#define AFX_CB_ADDSTRING 0x1234
if (nMsg == AFX_CB_ADDSTRING)
nMsg = CBEM_INSERTITEM;
else if (nMsg == WIN16_LB_ADDSTRING)
nMsg = LB_ADDSTRING;
else if (nMsg == WIN16_CB_ADDSTRING)
nMsg = CB_ADDSTRING;
ATLASSERT(nMsg == LB_ADDSTRING || nMsg ==
CB_ADDSTRING || nMsg == CBEM_INSERTITEM);
if (nMsg == CBEM_INSERTITEM)
{
USES_CONVERSION;
COMBOBOXEXITEM item;
item.mask = CBEIF_TEXT;
item.iItem = -1;
item.pszText = A2T(LPSTR(lpnRes));
if (::SendDlgItemMessage(m_hWnd, nIDC, nMsg,
0, (LPARAM) &item) == -1)
bSuccess = FALSE;
}
else if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING)
{
// List/Combobox returns -1 for error
int result = ::SendDlgItemMessage(m_hWnd,
nIDC, nMsg, 0, (LPARAM) lpnRes);
if (result == -1)
bSuccess = FALSE;
}
// skip past data
lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
}
}

近期评论