2Betterthanyou
Щойно працював з чимось схожим, не знаю як робляться ресурси в Resource-Definition Statements, але як контроли взаємодіть між собою трохи розібрався.
Для обробки повідомлень з інших контролів пишеться окрема процедура, схожа на WndProc. Зверніть увагу сигнатура в нєї трохи інша. Для того щоб оброблювати нею повідомлення від кнопки її треба зареєструвати але, не на кнопку, а на батьківський контрол кнопки(!), бо хоч повідомлення відправляє і кнопка та відправляє вона їх на батьківський контрол. Ниже приклад з поясненням.
Отже в нас є дочірнє вікно - панель (ряд. 85) і кнопка на цій панелі (ряд 102), для якої ця панель є батьківським контролом (ряд. 111). Також у кнопки є свій ідентифікатор (ряд.112) по якому потім можна буде її знайти.
Панель "реєструється" з кастомним WndProc - MyBeautifullWndProc (ряд. 8 ) за допомогою функції SetWindowSubclass (ряд. 99).
Коли якийсь контрол, для якого панель є батьківським контролом, відправляє повідомлення то воно приходить в наш MyBeautifullWndProc. А в MyBeautifullWndProc ми вже знаємо тип повідомлення (ряд. 10), і знаємо хто його відправив (ряд. 15) - відповідно реагуємо.
#include "stdafx.h"
#include <windows.h>
#include <CommCtrl.h>
static const long ID_CHILD_PANEL = 1;
static const long ID_BUTTON_PRESS_ME = 2;
LRESULT CALLBACK MyBeautifullWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_BUTTON_PRESS_ME:
MessageBox(NULL, L"You've pressed the \"Press me\" button??!", L"Wtf...?!", MB_ICONINFORMATION | MB_OK);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefSubclassProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Register wsndow class
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"SOME_CLASS_NAME";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
// Create the main windows
HWND vMainWindow = CreateWindowEx(
WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT,
L"SOME_CLASS_NAME",
L"Test app",
WS_OVERLAPPED | WS_SYSMENU,
700, 500,
840, 360,
NULL,
NULL,
hInstance,
(PVOID)NULL);
// Create the control panel
HWND vChildControl = CreateWindowEx(
WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME,
L"STATIC",
(PCTSTR)NULL,
WS_CHILD | WS_VISIBLE,
0,
260,
840,
50,
vMainWindow,
(HMENU)ID_CHILD_PANEL,
hInstance,
(LPVOID)NULL);
SetWindowSubclass(vChildControl, MyBeautifullWndProc, 0, 0);
// Create the button "Press me!"
HWND vButtomAtChildWindow = CreateWindowEx(
0,
L"BUTTON",
L"Press me!",
WS_VISIBLE | WS_CHILD | BS_FLAT,
705,
5,
100,
30,
vChildControl,
(HMENU)ID_BUTTON_PRESS_ME,
hInstance,
NULL);
ShowWindow(vMainWindow, SW_SHOW);
MSG Msg;
BOOL ret;
while ((ret = GetMessage(&Msg, NULL, 0, 0)) != 0)
{
if (ret == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return (int)Msg.wParam;
}
Надіюсь це буде корисним. Код робочий, тільки треба буде підключити в проект бібліотеку Comctl32.lib