Окна msys2 открываются в фоновом режиме, а не на HWND_TOPC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Окна msys2 открываются в фоновом режиме, а не на HWND_TOP

Сообщение Anonymous »

Я с удовольствием использую msys2 в сочетании с менеджером пакетов pacman для создания библиотеки. В библиотеке есть концепция окон, основанная на функциях HWND и winuser.h для создания окна и класса окна. Окна предназначены как окна верхнего уровня. Обычно я подозреваю, что окно при первом открытии соответствует ряду условий:
  • Они находятся поверх других окон (верхнего уровня). . (Я думаю, это то, что вы получаете, когда открываете, например, Chrome, Word и т. д., например, через панель задач Windows или меню «Пуск».
  • Это те, которые получают ввод с клавиатуры.
Что бы я ни делал, ни одно из вышеперечисленных условий не выполняется, как и все остальные открытые окна. значок моей программы мерцает оранжевым цветом на задаче полоса внизу.
Класс моего окна создается следующим образом и уничтожается, когда уничтожается и последнее из моих окон.

Код: Выделить всё

static void
create_window_class(void)
{
g_module_handle = GetModuleHandle(NULL);

WNDCLASSEX win_class;
memset(&win_class, 0, sizeof(win_class);
win_class.cbSize        = sizeof(win_class);
win_class.style         = CS_OWNDC;
win_class.lpfnWndProc   = startup_winproc;
win_class.hCursor       = LoadCursor(NULL, IDC_ARROW);
win_class.lpszClassName = g_win_class_name;

g_win_class  = (WNDCLASSEX*) g_malloc0(sizeof(WNDCLASSEX));
*g_win_class = win_class;

g_win_class_atom = RegisterClassEx(g_win_class);
if (g_win_class_atom == 0) {
char error_buf[1024];
psy_strerr(GetLastError(), error_buf, sizeof(error_buf));
g_critical("Unable to create WindowClass '%s': %s",
g_win_class_name,
error_buf);
}
}
И тогда окно создается следующим образом:

Код: Выделить всё

static void
win_window_constructed(GObject *object)
{
PsyWinWindow *self = PSY_WIN_WINDOW(object);
G_OBJECT_CLASS(psy_win_window_parent_class)->constructed(object);

DWORD win_style = WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_CAPTION;
DWORD win_style_ex = WS_EX_OVERLAPPEDWINDOW;

gint nth_mon = psy_window_get_monitor(PSY_WINDOW(self));
g_assert(nth_mon >= 0 && (guint) nth_mon < self->display_info->len);
PsyDisplayInfo *desired_monitor = self->display_info->pdata[nth_mon];
PsySize        *size            = desired_monitor->rect->size;
PsyPos         *pos             = desired_monitor->rect->pos;

RECT r;
r.bottom = 480,    // pos->y + size->height;
r.top    = pos->x, // pos->y;
r.right  = 640,    // pos->x + size->width;
r.left   = pos->y, // pos->x;

// We could use AdjustWindowRectEx to set the client size to the desired
// size however, we try just to create a window at fullscreen size
// AdjustWindowRectEx(&r, win_style, FALSE, win_style_ex);

self->window = CreateWindowEx(win_style_ex,
g_win_class_name,
"psy_window",
win_style,
r.left,
r.top,
r.right - r.left,
r.bottom - r.top,
NULL,
NULL,
g_module_handle,
self);
if (!self->window) {
char error_buff[1024];
psy_strerr(GetLastError(), error_buff, sizeof(error_buff));
g_critical("Unable to create window: %s", error_buff);
return;
}

BOOL success;
ShowWindow(self->window, SW_SHOWMAXIMIZED);

// Try to set it to the top in the Z-order, this functions
// succeeds, however, the windows Z-order policy doesn't
// allow the monitor to go to the top. Only once the user
// clicks it, it will go to the top.  Currently, the window
// will flicker it's icon on the task bar.
//
// Also show the window.
success = SetWindowPos(self->window,
HWND_TOP,
0,
0,
0,
0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW);
if (!success) {
char error_buf[1024];
psy_strerr(GetLastError(), error_buf, sizeof(error_buf));
g_critical("Unable to set window pos: %s", error_buf);
}

success = SetForegroundWindow(self->window);
if (!success) {
char error[1024];
psy_strerr(GetLastError(), error, sizeof(error));
g_critical(
"%s: Unable to set window to foreground: %s", __func__, error);
}

PsyD3dContext *context
= psy_d3d_context_new_full(self, 1, self->enable_debug);
psy_canvas_set_context(PSY_CANVAS(self), PSY_DRAWING_CONTEXT(context));
}
Я запускаю свои программы с помощью терминала msys2.

Код: Выделить всё

./some/path/myprogram.exe
Я вижу всплывающее окно, да, под ним. Я вижу свою программу на панели задач, и если я использую SetForegroundWindow(self->window), я вижу, что значок на панели задач мерцает оранжевым цветом. Я получаю такие сообщения, как WM_CREATE, WM_ACTIVATE (хотя я получаю сообщение, что клавиатура остается с msys2, например, нажатие alt + f4 закроет терминал msys2, а не мое окно).
В некоторых крайних случаях соблюдаются два вышеуказанных пункта.
  • Я запускаю команду через gdb, например. gdb ./some/path/myprogram.exe
  • Я запускаю cmd и запускаю программу оттуда, она работает только в первый раз.
  • Я могу использовать HWND_TOPMOST с SetWindowPosition, но в этом случае окно появляется только над другими, даже когда я переключаюсь на другое окно с помощью alt+tab или щелчка мыши, и даже тогда ввод с клавиатуры не фокусируется на моей программе. Кроме того, после того, как окно станет видимым, я хочу, чтобы пользователи могли переключиться на окно по своему выбору. У меня нет намерения бороться с z-порядком окон.
Теперь это может быть как-то связано с запуском программ с терминала msys2.
Если я запускаю Chrome через терминал msys2, кажется, что он также появляется под другими окнами.
Я запускаю это в Windows 10, версия 22H2
Поэтому мой вопрос сводится к следующему: почему программы, запускаемые через msys2, скорее появляются, а не всплывающие, и почему фокус клавиатуры не направляется на вновь открытые окна?

Подробнее здесь: https://stackoverflow.com/questions/793 ... t-hwnd-top
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»