Я хотел включить функциональность панели задач в свое приложение Flutter, поэтому я решил изменить собственный код C ++, который запускает окно и т. Д., Чтобы посмотреть, смогу ли я подключиться к нему. Несмотря на то, что у меня не было большого опыта работы с C ++, я смог создать значок для своего приложения в системном трее с меню, которое позволяет отображать окно снова, когда оно скрыто (с помощью ShowWindow(hwnd, SW_HIDE);), и полностью закрывать его.

Однако, когда в моем меню панели задач выбрана опция для повторного отображения окна с помощью ShowWindow(hwnd, SW_NORMAL); после того, как оно было скрыто, приложение остается пустым, как это:

enter image description here

Затем, когда окно, наконец, взаимодействует с окном, снова отображается содержимое окна:

enter image description here

Вот код, который я добавил в свой win32_window.cpp (из стандартного приложения Flutter). Я не включил все функции, потому что думал, что это сделает ситуацию менее ясной, но я также приложу полный файл win32_window.cpp в конце этого сообщения. Win32Window :: CreateAndShow ():

//Systray:
HICON hMainIcon;
hMainIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICON));
nidApp.cbSize = sizeof(NOTIFYICONDATA); // sizeof the struct in bytes
nidApp.hWnd = (HWND) window;              //handle of the window which will process this app. messages
nidApp.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; //ORing of all the flags
nidApp.hIcon = hMainIcon; // handle of the Icon to be displayed, obtained from LoadIcon
nidApp.uCallbackMessage = WM_USER_SHELLICON;
StringCchCopy(nidApp.szTip, ARRAYSIZE(nidApp.szTip), L"All Platforms Test");
Shell_NotifyIcon(NIM_ADD, &nidApp);

return OnCreate();

Win32Window :: WndProc ():

if (message == WM_NCCREATE) { ... }
else if (message == WM_USER_SHELLICON) { //interacting with systray icon
    if (LOWORD(lparam) == WM_RBUTTONDOWN) { //right clicked
        POINT lpClickPoint;
        GetCursorPos(&lpClickPoint);
        hPopMenu = CreatePopupMenu();
        InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,IDM_SHOW,_T("Show"));
        InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,IDM_EXIT,_T("Quit"));
        SetForegroundWindow(window);
        TrackPopupMenu(hPopMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_BOTTOMALIGN,lpClickPoint.x, lpClickPoint.y,0,window,NULL);
    }
    else if (LOWORD(lparam) == WM_LBUTTONDOWN) { //left clicked
        ShowWindow(window, SW_NORMAL);
        //LOOK: works but shows blank screen until is interacted with (mouse enters or key is pressed etc)
    }
}
else if (message == WM_COMMAND) { //if message is a command event such as a click on the exit menu option
    int wmId;
    wmId = LOWORD(wparam);

    if (wmId == IDM_EXIT) { //if quit has been pressed
        Shell_NotifyIcon(NIM_DELETE,&nidApp);
        DestroyWindow(window);
    }
    else if (wmId == IDM_SHOW) {
        ShowWindow(window, SW_NORMAL);
        //LOOK: works but shows blank screen until is interacted with (mouse enters or key is pressed etc)
    }

Win32Window :: MessageHandler ():

switch (message) {
  ...
  case WM_CLOSE: //stop window from closing normally, can only be closed when DestroyWindow() is run from systray
    //Hide window and continue running in background.
    ShowWindow(hwnd, SW_HIDE);
    return 0;
}

Ссылка на полный файл win32_window.cpp здесь.

Что тут происходит? Я думал, что использование UpdateWindow () поможет, но потом я понял, что приложение все равно нарисовано на ShowWindow (). Я предполагаю, что это как-то связано с блокировкой цикла выполнения Flutter, но я не могу понять, куда идти дальше, особенно учитывая, что я обычно не балуюсь C ++, а просто хотел добавить дополнительную функцию в свое приложение при запуске в Windows.

Любая помощь будет принята с благодарностью, спасибо.

0
Letal1s 18 Май 2021 в 20:51

1 ответ

Лучший ответ

Хорошо, я понял, почему это не работает. При закрытии окна я не мог просто использовать SW_HIDE, но и SW_MINIMIZE тоже. В противном случае попытка перерисовки окна не сработает:

ShowWindow(hwnd, SW_MINIMIZE);
ShowWindow(hwnd, SW_HIDE);

После этого при отображении окна оно было нарисовано, но не было активным окном, но добавление SetForegroundWindow () исправило это:

ShowWindow(window, SW_NORMAL);
SetForegroundWindow(window);

Спасибо всем за помощь :)

0
Letal1s 20 Май 2021 в 20:29