WinAPI - получить прокручиваемую рамку для рисования - PullRequest
0 голосов
/ 03 июля 2019

Я кодирую алгоритм, который вычисляет последовательности через более прохладные тела как летняя работа. Сам алгоритм готов, и я начал изучать создание простого графического интерфейса на C ++, в котором вы можете создавать последовательности для конкретной комбинации кулеров, а также иметь возможность просматривать ее заранее. Это не то, что я делал раньше.

У меня есть кое-что довольно простое для работы, и сейчас я рисую, как последовательности выглядят прямо в главном окне. Что может быть труднее вместо этого нарисовать его в прокручиваемом «кадре» в том же главном окне? В настоящее время большие комбинации слишком велики, чтобы поместиться на одном экране, и просто увеличить окно недостаточно. Спасибо за любую помощь!

Я попытался создать статическое изображение со стилем "WS_VSCROLL" и использовать "hdc = GetDC (hWndNewStatic)", которое я немного поработал с рисованием, но потом оно снова не сработало. Полоса прокрутки не работает.

пример программы ПОС

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{

    WNDCLASSEX wcex = {};
    wcex.cbClsExtra = 0;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.cbWndExtra = 0;
    wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE (IDI_ICON));
    wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE (IDI_ICON));
    wcex.hInstance = hInstance;
    wcex.lpfnWndProc = WndProc;
    wcex.lpszClassName = TEXT("WinApp");
    wcex.lpszMenuName = NULL;
    wcex.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL, TEXT("RegisterClassEx Failed!"), TEXT("Error"), MB_ICONERROR);
        return EXIT_FAILURE;
    }

    HWND hWnd = CreateWindow(
        TEXT("WinApp"), TEXT("SeqGen"),
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT,
        NULL, NULL, hInstance, NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL, TEXT("CreateWindow Failed!"), TEXT("Error"), MB_ICONERROR);
        return EXIT_FAILURE;
    }

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    hdc = GetDC(hWnd);

    // Messages
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (IsDialogMessage(hWnd, &msg))
        {}
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return EXIT_SUCCESS;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    LPCSTR moduleValue;
    static int index {};
    static unsigned module {0};
    static bool draw {false};

    switch (msg)
    {
        case WM_CREATE:
            hWndStatic = CreateWindow(
                TEXT("Static"), TEXT("Tube rows"),
                WS_CHILD | WS_VISIBLE,
                30, 20, 100, 24,
                hWnd, NULL, NULL, NULL
            );

            hWndStatic = CreateWindow(
                TEXT("Static"), TEXT("Water passes"),
                WS_CHILD | WS_VISIBLE,
                130, 20, 100, 24,
                hWnd, NULL, NULL, NULL
            );

            hWndStatic = CreateWindow(
                TEXT("Static"), TEXT("Multiples"),
                WS_CHILD | WS_VISIBLE,
                230, 20, 100, 24,
                hWnd, NULL, NULL, NULL
            );

            hWndrr = CreateWindowEx(
                WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""),
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                30, 50, 50, 24,
                hWnd, NULL, NULL, NULL
            );

            hWndvv = CreateWindowEx(
                WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""),
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                130, 50, 50, 24,
                hWnd, NULL, NULL, NULL
            );

            hWndN = CreateWindowEx(
                WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT("0"),
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                230, 50, 50, 24,
                hWnd, NULL, NULL, NULL
            );

            hWndList = CreateWindow(
                TEXT("ListBox"), TEXT(""),
                WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | WS_BORDER | LBS_NOTIFY,
                20, 150, TEXTBOX_WIDTH, TEXTBOX_HEIGHT,
                hWnd, (HMENU) LST_RESULT, NULL, NULL
            );


            hWndCreateall = CreateWindow(
                TEXT("Button"), TEXT("Create all DIR"),
                WS_CHILD | WS_VISIBLE,
                50, 90, 100, 24,
                hWnd, (HMENU) BTN_CREATEALL, NULL, NULL
            );   

            hWndButton = CreateWindow(
                TEXT("Button"), TEXT("Create DIR"),
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                200, 90, 100, 24,
                hWnd, (HMENU) BTN_CREATE, NULL, NULL
            );   

            break;

        case WM_COMMAND:
            switch (HIWORD(wParam))
            {
                case LBN_SELCHANGE:
                    if (LOWORD(wParam) == LST_RESULT)
                    {
                        index = SendMessage(hWndList, LB_GETCURSEL, 0, 0);

                        if (index >= 0)
                        {
                            module = 0;
                            moduleValue = (to_string(module).c_str());
                            SetWindowText(hWndStaticModule, moduleValue);
                            draw = true;
                            RedrawWindow(hWnd, 0, 0, RDW_INVALIDATE);
                        }
                    }
                    break;

                case BN_CLICKED:
                    switch (LOWORD(wParam))
                    {
                        case BTN_CREATE:
                            --stuff for creating combination--

                            break;

                        case BTN_CREATEALL:
                            --stuff for creating all possible combination--

                            break;
                    }

                    break;

                default:
                    break;
            }
            break;

        case WM_PAINT:
            if (draw)
            {
                --function for drawing stuff on main window--

                draw = false;
            }
            UpdateWindow(hWnd);

            break;

        case WM_DESTROY:
            PostQuitMessage(EXIT_SUCCESS);

        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return FALSE;
}

1 Ответ

1 голос
/ 03 июля 2019

Вам нужно много кода, чтобы достичь того, что вам нужно, и я могу лишь дать вам теоретическое объяснение необходимых компонентов.

  1. Класс панели .Для панели нужен собственный класс окна со своим собственным оконным процессом.Panel proc должна обработать WM_VSCROLL и, возможно, WM_HSCROLL, вручную , установив новое значение прокрутки с помощью SetScrollPos и сохранив его в некоторой переменной состояния.Ваш обработчик WM_*SCROLL теперь имеет две опции:
    • Позвоните InvalidateRect и позвольте WM_PAINT обновить всю панель.
    • Позвоните ScrollWindow, чтобы переместить реальную графику, а затем позвоните UpdateWindowобновить открытую область.
  2. Алгоритм рисования для панели .Вы должны отреагировать на WM_PAINT отрисовку вашей модели, как обычно, но координаты y должны быть смещены на переменную состояния прокрутки.У вас есть несколько вариантов:
    • Перерисовать все окно.
    • Нарисуйте содержимое нового окна на внеэкранном HDC, а затем разбить бит на весь экран.
    • Перерисоватьоткрытая область (см. предыдущий пункт о ScrollWindow)
  3. Экземпляр панели в главном окне.Основной выигрыш выделит панель как дочернее окно, как и для других элементов управления, также указав WS_VSCROLLWS_HSCROLL?) И настроив размер прокрутки с помощью SetScrollInfo, в соответствии с размером документа.Главный выигрыш также должен реагировать на WM_SIZE, чтобы изменить размер (MoveWindow) панели, придав ей новый размер.Новый размер рассчитывается путем вычитания необходимого вам отступа из клиентской области основного выигрыша.

Каждый крошечный бит в конечном итоге будет нуждаться в дальнейшем поиске в Google и публикации на SO.

Вы также можете рассмотретьрисование с использованием OpenGL, DirectX или просто GDI + (что, в свою очередь, может открыть множество других вопросов).

...