#cpp #winapi
Имеется большое количество кнопок и такое же количество радиокнопок. Нужно что бы
при нажатии кнопки параллельно включалась радио кнопка, после выбираем другую кнопку
- она становится вдавленной, а та которая была нажата становится ненажатой.
Не получаются две вещи:
1) не могу найти функции, чтобы сделать кнопку вдавленной (нажатой),
поэтому заменила пока на EnableWindow;
2) не могу отжать ту кнопку которая была нажата ранее (т.к. если
например делать циклом, то получается нецелесообразно из-за времени,
т.к. кнопок может быть 80000). И глобалить нельзя.
#include
#define sizemas 4
#define ID_CUR 3
#define ID_BUTTON 125
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASS wclass = { 0 };
POINT p = { 0 };
wclass.hInstance = hInstance;
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wclass.lpfnWndProc = WindowProc;
wclass.lpszClassName = "WinName";
wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
if (!RegisterClass(&wclass))
return 0;
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);
HWND hwnd = CreateWindow(
wclass.lpszClassName,
"Main",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
0.6*x,
0.6*y,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
char buff[1024] = { 0 };
HWND hButton[sizemas + 1], hRadioButton[sizemas + 1];
for (int i = 1; i <= sizemas; i++) {
wsprintf(buff, "Кнопка %d", i);
hButton[i] = CreateWindow("BUTTON", buff, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
30, 60 * i, 240, 50, hwnd, (HMENU)(ID_BUTTON + i), hInstance, NULL);
}
for (int i = 1; i <= sizemas; i++) {
hRadioButton[i] = CreateWindow("BUTTON", "RadioButton ", BS_AUTORADIOBUTTON
| WS_VISIBLE | WS_CHILD, 630, 60 * i, 240, 50, hwnd, (HMENU)(ID_BUTTON + i + sizemas),
hInstance, NULL);
}
CheckDlgButton(hwnd, ID_CUR + ID_BUTTON + sizemas, 1);
EnableWindow(GetDlgItem(hwnd, ID_CUR + ID_BUTTON), false);
SetWindowLong(hwnd, GWL_USERDATA, (LONG)&p);
while (GetMessage(&msg, NULL, 0, 0))
DispatchMessage(&msg);
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg)
{
case WM_COMMAND: {
POINT *p = (POINT *)GetWindowLong(hwnd, GWL_USERDATA);
if (LOWORD(wParam) > ID_BUTTON && LOWORD(wParam) <= (sizemas + ID_BUTTON)) {
if ((LOWORD(wParam) + ID_CUR - 1) != (ID_CUR + ID_BUTTON)) {
CheckDlgButton(hwnd, p->x + sizemas, 0);
EnableWindow(GetDlgItem(hwnd, p->x), true);
}
CheckDlgButton(hwnd, LOWORD(wParam) + sizemas, BST_CHECKED);
EnableWindow(GetDlgItem(hwnd, LOWORD(wParam)), false);
p->x = LOWORD(wParam);
SetWindowLong(hwnd, GWL_USERDATA, (LONG)&p);
}
/*if (LOWORD(wParam) > (ID_BUTTON + sizemas)) {
for (int i = 1; i <= sizemas; i++) {
EnableWindow(GetDlgItem(hwnd, ID_BUTTON + i), true);
}
CheckDlgButton(hwnd, LOWORD(wParam), BST_CHECKED);
EnableWindow(GetDlgItem(hwnd, LOWORD(wParam) - sizemas), false);
}*/
return 0;
}
case WM_SIZE:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Ответы
Ответ 1
Это достаточно просто, кнопки можно сгруппировать для автоматического переключения внутри группы используя стиль WS_GROUP и BS_AUTORADIOBUTTON. Так как тут группы две (кнопки и радио кнопки) то переключить кнопку в противоположной группе нужно руками // глобальные const int buttons_count = 4; const int buttons_id_delta = 1000; const int buttons_id_first = 100; int checked_button_id = 0; int checked_radio_button_id = 0; // создаем окна DWORD window_style; int button_index; // создаем кнопки, первая будет иметь доп стиль WS_GROUP window_style = WS_GROUP | BS_PUSHLIKE | BS_AUTORADIOBUTTON | WS_VISIBLE | WS_CHILD; button_index = 0; do { CreateWindowW(L"BUTTON", L"Test", window_style, 30, 60 * button_index, 240, 50, hWnd , (HMENU) (buttons_id_first + button_index), NULL, NULL); window_style = BS_PUSHLIKE | BS_AUTORADIOBUTTON | WS_VISIBLE | WS_CHILD; ++button_index; } while(buttons_count != button_index); // создаем радиокнопки, первая будет иметь доп стиль WS_GROUP window_style = WS_GROUP | BS_AUTORADIOBUTTON | WS_VISIBLE | WS_CHILD; button_index = 0; do { CreateWindowW(L"BUTTON", L"Test", window_style, 300, 60 * button_index, 240, 50, hWnd , (HMENU) (buttons_id_first + buttons_id_delta + button_index), NULL, NULL); window_style = BS_AUTORADIOBUTTON | WS_VISIBLE | WS_CHILD; ++button_index; } while(buttons_count != button_index); // обработчик сообщений LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { const int control_id = LOWORD(wParam); if ( (buttons_id_first <= control_id) && (control_id < (buttons_id_first + buttons_count)) ) { // пользователь нажал на кнопку checked_button_id = control_id; // выключаем ранее нажатую радио кнопку if(0 != checked_radio_button_id) { SendMessage(GetDlgItem(hWnd, checked_radio_button_id), BM_SETCHECK, BST_UNCHECKED, 0); } // включаем новую радио кнопку checked_radio_button_id = control_id + buttons_id_delta; SendMessage(GetDlgItem(hWnd, checked_radio_button_id), BM_SETCHECK, BST_CHECKED, 0); } else if ( ((buttons_id_first + buttons_id_delta) <= control_id) && (control_id < (buttons_id_first + buttons_id_delta + buttons_count)) ) { // пользователь нажал на радио кнопку checked_radio_button_id = control_id; // выключаем ранее нажатую кнопку if(0 != checked_button_id) { SendMessage(GetDlgItem(hWnd, checked_button_id), BM_SETCHECK, BST_UNCHECKED, 0); } // включаем новую кнопку checked_button_id = control_id - buttons_id_delta; SendMessage(GetDlgItem(hWnd, checked_button_id), BM_SETCHECK, BST_CHECKED, 0); } else { // прочее... break; } // обязятельно вызываем DefWindowProc(hWnd, message, wParam, lParam); break; } результат:
Комментариев нет:
Отправить комментарий