#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; } результат:
Комментариев нет:
Отправить комментарий