Здесь на самом деле нет чистого решения.
Вы можете убедиться, что все дочерние элементы управления вычитают OCM__BASE
при вызове DefWindowProc()
для необработанных OCM_...
сообщений.
LRESULT WINAPI DefChildProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
switch (umsg) {
...
}
if ((umsg >= OCM__BASE) && (umsg <= OCM__MAX)) {
umsg -= OCM__BASE;
}
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
В противном случае каждое сообщение OCM_...
может содержать указатель на структуру в WPARAM
или LPARAM
, где структура содержит действительное значение WPARAM
/ LPARAM
и вывод * 1016.*, а затем каждый дочерний элемент управления может возвращать TRUE
, если обрабатывается данное сообщение OCM_...
.Затем родитель может вызвать DefWindowProc()
с исходным сообщением WM_...
, если SendMessage(OCM_...)
вернет FALSE.
struct OCMInfo
{
LPARAM lParam;
LRESULT lResult;
};
LRESULT WINAPI DefParentProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
switch (umsg) {
case WM_NOTIFY:
{
NMHDR* nmhdr = (NMHDR*)lparam;
if (nmhdr->hwndFrom != NULL)
{
OCMInfo info;
info.lParam = lParam;
info.lResult = 0;
if (SendMessage(nmhdr->hwndFrom, umsg + OCM__BASE, wparam, (LPARAM)&info))
return info.lResult;
}
break;
}
// All of these provide the control's HHWND in LPARAM
case WM_COMMAND:
case WM_CTLCOLORBTN:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORDLG:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
case WM_VKEYTOITEM:
case WM_CHARTOITEM:
if (lparam != 0)
{
OCMInfo info;
info.lParam = lParam;
info.lResult = 0;
if (SendMessage((HWND)lparam, umsg + OCM__BASE, wparam, (LPARAM)&info))
return info.lResult;
}
break;
// All of these provide ID of the control in WPARAM:
case WM_DRAWITEM:
case WM_MEASUREITEM:
case WM_DELETEITEM:
case WM_COMPAREITEM:
if (wparam != 0) {
HWND hwndControl = GetDlgItem(hwnd, wparam);
if (hwndControl)
{
OCMInfo info;
info.lParam = lParam;
info.lResult = 0;
if (SendMessage(hwndControl, umsg + OCM__BASE, wparam, (LPARAM)&info))
return info.lResult;
}
}
break;
// Note we do not reflect WM_PARENTNOTIFY -> OCM_PARENTNOTIFY as that
// usually does not make much sense.
}
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
LRESULT WINAPI DefChildProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
switch (umsg) {
case OCM__NOTIFY:
{
OCMInfo* info = (OCMInfo*)lparam;
NMHDR* nmhdr = (NMHDR*)(info->lparam);
if (...) {
...
info->lResult = ...;
return TRUE;
}
break;
}
case OCM__COMMAND:
{
OCMInfo* info = (OCMInfo*)lparam;
if (...) {
...
info->lResult = ...;
return TRUE;
}
break;
}
...
}
return DefWindowProc(hwnd, umsg, wparam, lparam);
}