WINAPI CreateWindow, отображающий странные результаты

0

У меня проблемы с проектом WINAPI. Есть две проблемы, когда я запускаю окно с приведенным ниже кодом, параметр высоты ведет себя странно. Кажется, он закрывается на 1092, 18 пикселей ниже, где мне это нужно на моем компьютере. Вторая проблема заключается в том, что в окне нет краев или верхней панели меню, пока я не использую комбинацию клавиш Windows + Up/Down, чтобы минимизировать и максимизировать ее, тогда она ведет себя нормально. Я использую приведенный ниже код для инициализации окна (единственный код, который выполняется до этого, инициализирует options.pxXRes и другие переменные, используемые ниже):

//Set up the window class
WNDCLASSEX wndClass;
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = &WndHandleInput;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = GetModuleHandle(nullptr);


wndClass.hIcon = nullptr;
wndClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wndClass.lpszMenuName = nullptr;
wndClass.lpszClassName = "ToastCatClass";
wndClass.hIconSm = nullptr;

RegisterClassEx(&wndClass);

RECT wndRect;
if (options.fullscreen) {
    wndRect.left = 0;
    wndRect.right = options.pxXRes;
    wndRect.top = 0;
    wndRect.bottom = options.pxYRes;
    AdjustWindowRect(&wndRect, WS_OVERLAPPEDWINDOW, false);
} else {
    wndRect.left = (GetPXXRes() - options.pxXRes) / 2;
    wndRect.right = options.pxXRes;
    wndRect.top = (GetPXYRes() - options.pxYRes) / 2;
    wndRect.bottom = options.pxYRes;
    AdjustWindowRect(&wndRect, WS_OVERLAPPEDWINDOW, false);
}

hWnd = CreateWindowEx(
    0,
    wndClass.lpszClassName,
    "ToastCat",
    WS_OVERLAPPEDWINDOW,
    wndRect.left,
    wndRect.top,
    wndRect.right - wndRect.left,
    wndRect.bottom - wndRect.top,
    nullptr,
    nullptr,
    wndClass.hInstance,
    nullptr
);

assert(hWnd != nullptr, "Failure to launch window.");

ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

Процедура Window выглядит следующим образом:

LRESULT __stdcall WndHandleInput(HWND hWndParam, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
    case WM_NCCREATE:
        return true;
    case WM_KEYDOWN:
        switch (wParam) {
            //TODO: Update controls
        }
        break;
    case WM_KEYUP:
        switch (wParam) {
            //TODO: Update controls
        }
        break;
    case WM_CLOSE:
    case WM_QUIT:
        Cleanup();
        break;
    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }

    return 0;
}
  • 0
    1) Почему вы используете CS_OWNDC ? 2) Ваши вызовы assert() не будут работать; assert() принимает один параметр, так что , становится (в сравнении) неясной функция C называется выражение запятой, которая отбрасывает левую сторону и возвращает правую сторону, что в вашем случае является строковым, что ненулевой указатель, что всегда верно.
  • 1
    3) Что произойдет, если вы WM_NCCREATE до DefWindowProc() вместо того, чтобы обрабатывать его самостоятельно?
Показать ещё 1 комментарий
Теги:
winapi
win32gui

1 ответ

2
Лучший ответ

Windows имеет два разных прямоугольника:

  • клиентский прямоугольник, который является областью окна, к которой приложение может рисовать или создавать дочерние окна внутри и
  • прямоугольник окна, который является внешним прямоугольником окна (включая границы, меню,...).

AdjustWindowRect вы конвертируете прямоугольник клиента в прямоугольник окна. Поэтому границы и меню не могут быть видны, если вы настраиваете прямоугольник клиента размером с весь экран, преобразовывая его в прямоугольник окна и создавая окно с таким размером. Если вы посмотрите на wndRect после вызова функции AdjustWindowRect(..) с помощью отладчика, вы увидите, что top и left отрицательные.

То, что высота окна отключена на некоторые пиксели, - это поведение окон по умолчанию. Windows по умолчанию не позволяет окнам иметь высоту, большую, чем высота экрана, потому что это приведет к перемещению субтитров из области, к которой может добраться мышь. Чтобы изменить это, вам необходимо обработать сообщение WM_GETMINMAXINFO:

case WM_GETMINMAXINFO:
    DefWindowProc(hWnd, msg, wParam, lParam);
    MINMAXINFO *pmmi = (MINMAXINFO*)lParam;
    pmmi->ptMaxTrackSize.x *= 2;   // just make it bigger...
    pmmi->ptMaxTrackSize.y *= 2;   // 
    return 0;

Если вы просто хотите запустить свое окно либо максимизировано (со всеми видимыми элементами управления и границей), либо в каком-либо другом определенном месте, выполните следующие действия: Создайте свое окно обычно с помощью wndRect инициализированного внутри else-части if (options.fullscreen) и измените вызов ShowWindow(..) следующим образом:

if (options.fullscreen)
{
    ShowWindow(hWnd, SW_MAXIMIZE);
}
else
{
    ShowWindow(hWnd, SW_SHOWDEFAULT);
}
UpdateWindow(hWnd);
  • 0
    Полноэкранное поведение было задумано (это графическое приложение, поэтому мне не нужны были видимые элементы управления, я просто подумал, что странно, что они не отображались). В любом случае, WM_GETMINMAXINFO это исправило. Я не знал, что CreateWindow ограничил его параметры по умолчанию. Большое спасибо за вашу помощь!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню