Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Сделать предыдущую кнопку не нажатой (не выпуклой)

#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; } результат:

Комментариев нет:

Отправить комментарий