Как сделать переход по элементам управления (э.у.) при нажатии <Tab>
В книжке Ч.Петзолд "Программирование для Windows 95" написано, что для этого нужно "введение новой оконной процедуры" (window subclassing). В тестовом примере я сделал почти так, как написано в книжке, за исключением: 1) у меня вместо 3 полос прокрутки - 3 кнопки; 2) у меня э.у. не в главном окне а в модальном. И код вынесен в модуль "Options.cpp", поэтому пришлось сделать static WNDPROC foptions[3]; иначе без волшебного слова static программа не компилируется.
В итоге программа компилируется, а потом при выполнении вываливается с ошибкой (см рисунок)
Вопрос как же сделать этот субклассинг?
Добавлено через 42 секунды
| Код | // Options.cpp
#include "Options.h"
void Options::CreateDlg(HINSTANCE hinstance) { InitCommonControls(); WNDCLASSEX w; w.cbSize = sizeof(w); w.cbClsExtra = 0; w.cbWndExtra = 0; w.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); w.hCursor = LoadCursor(NULL, IDC_ARROW); w.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_ICON_D)); w.hIconSm = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_ICON_D)); w.hInstance = hinstance; w.lpfnWndProc = WndProcOptions; w.lpszClassName = STR_OPTIONS; w.lpszMenuName = NULL; w.style = CS_HREDRAW | CS_VREDRAW; RegisterClassEx(&w); }
void Options::ShowDlg(HWND hwnd, HINSTANCE hinstance) { HWND hdlg; POINT point; RECT rect; DWORD dwStyle; EnableWindow(hwnd, FALSE); dwStyle = WS_POPUPWINDOW | WS_CAPTION; hdlg = CreateWindow(STR_OPTIONS, " Options", dwStyle, 0, 0, 0, 0, hwnd, NULL, hinstance, NULL); GetWindowRect(hwnd, &rect); point.x = (long) (rect.left + (rect.right - rect.left - INT_OPTIONS_WIDTH) / 2); point.y = (long) (rect.top + (rect.bottom - rect.top - INT_OPTIONS_HEIGHT) / 2); MoveWindow(hdlg, point.x, point.y, INT_OPTIONS_WIDTH, INT_OPTIONS_HEIGHT, FALSE); ShowWindow(hdlg, SW_SHOW); // dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON; hoptionsbutton[0] = CreateWindowEx(0, WC_BUTTON, NULL, dwStyle, 232, 365, 75, 23, hdlg, (HMENU) 1001, hinstance, NULL); // Apply ShowWindow(hoptionsbutton[0], SW_SHOW); hoptionsbutton[1] = CreateWindowEx(0, WC_BUTTON, NULL, dwStyle, 315, 365, 75, 23, hdlg, (HMENU) 1002, hinstance, NULL); // OK ShowWindow(hoptionsbutton[1], SW_SHOW); hoptionsbutton[2] = CreateWindowEx(0, WC_BUTTON, NULL, dwStyle, 398, 365, 75, 23, hdlg, (HMENU) 1003, hinstance, NULL); // Cancel ShowWindow(hoptionsbutton[2], SW_SHOW); foptions[0] = (WNDPROC) SetWindowLong(hoptionsbutton[0], GWL_WNDPROC, (LONG) WndProcOptionsButton); foptions[1] = (WNDPROC) SetWindowLong(hoptionsbutton[1], GWL_WNDPROC, (LONG) WndProcOptionsButton); foptions[2] = (WNDPROC) SetWindowLong(hoptionsbutton[2], GWL_WNDPROC, (LONG) WndProcOptionsButton); }
Options::Options() { }
Options::~Options() { }
LRESULT CALLBACK WndProcOptions(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { HWND hparent; int i; hparent = GetParent(hwnd); switch (message) { case WM_KEYDOWN: switch (LOWORD(wparam)) { case VK_ESCAPE: SendMessage(hwnd, WM_CLOSE, NULL, NULL); break; default: break; } return 0; case WM_COMMAND: i = GetWindowLong((HWND) lparam, GWL_ID); switch (LOWORD(wparam)) { case 1001: MessageBox(hwnd, "WM_COMMAND 1001", "Message", MB_OK); break; case 1002: MessageBox(hwnd, "WM_COMMAND 1002", "Message", MB_OK); break; case 1003: MessageBox(hwnd, "WM_COMMAND 1003", "Message", MB_OK); break; default: break; } return 0; case WM_CLOSE: EnableWindow(hparent, TRUE); SetFocus(hparent); BringWindowToTop(hparent); DestroyWindow(hwnd); return 0; } return DefWindowProc(hwnd, message, wparam, lparam); }
LRESULT CALLBACK WndProcOptionsButton(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { int i = GetWindowLong(hwnd, GWL_ID); switch (message) { case WM_KEYDOWN: if (wparam == VK_TAB) SetFocus(hoptionsbutton[(i+(GetKeyState(VK_SHIFT) < 0 ? 2 : 1)) % 3]); break; case WM_SETFOCUS: ifocus = i; break; } return CallWindowProc(foptions[i], hwnd, message, wparam, lparam); }
|
Добавлено через 1 минуту и 38 секунд
| Код | // Options.h
#include <windows.h> #include <commctrl.h> #include "resource.h"
#pragma comment (lib, "comctl32.lib")
#define STR_OPTIONS "ClassOptions" #define INT_OPTIONS_WIDTH 485 #define INT_OPTIONS_HEIGHT 420
static HICON hiconoptions; static HWND hoptionsbutton[3]; static WNDPROC foptions[3]; static int ifocus;
class Options { public: void CreateDlg(HINSTANCE hinstance); void ShowDlg(HWND hwnd, HINSTANCE hinstance); Options(); ~Options(); };
LRESULT CALLBACK WndProcOptions(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); LRESULT CALLBACK WndProcOptionsButton(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
|