Как сохранить MDI окно всегда поверх остальных

Проблема в том, что не существует стилей для того, чтобы вновь создаваемое MDI окно было всегда поверх остальных MDI окон. Однако, существуют два способа решения данной задачи:

  • Обработать сообщение WM_WINDOWPOSCHANGED и вызвать SetWindowPos() чтобы изменить Z-порядок окна.

  • Создать таймер для MDI окон и сбросить Z-порядок окна при обработке сообщения WM_TIMER.

MDICREATESTRUCT имеет поле "style", которое может быть установлено со стилями для нового MDI окна. Расширенные стили, такие как WS_EX_TOPMOST, не доступны для MDI окон. Это поле в структуре MDICREATESTRUCT передаётся в CreateWindowEx() в параметре dwStyle. Поле dwExStyle установлено в 0L. Два метода, показанные ниже, не могут быть использованы в одно и тоже время в одном приложении.

Первый метод: Обрабатываем сообщение WM_WINDOWPOSCHANGED и вызываем SetWindowPos() чтобы изменить Z-порядок окна.

Пример кода

 LRESULT CALLBACK MdiWndProc (HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
static HWND hWndAlwaysOnTop = 0;
switch (message)
{
case WM_CREATE :
if (!hWndAlwaysOnTop)
{
SetWindowText (hWnd, "Always On Top Window");
hWndAlwaysOnTop = hWnd;
}
break;
case WM_WINDOWPOSCHANGED :
if (hWndAlwaysOnTop)
{
WINDOWPOS FAR* pWP = (WINDOWPOS FAR*)lParam;
if (pWP->hwnd != hWndAlwaysOnTop)
SetWindowPos (hWndAlwaysOnTop, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
break;
//
// Здесь обрабатываются остальные сообщения.
//
case WM_CLOSE :
if (hWndAlwaysOnTop == hWnd)
hWndAlwaysOnTop = NULL;
default :
return DefMDIChildProc (hWnd, message, wParam, lParam);
}
return 0L;
}

Второй метод: Устанавливаем таймер для MDI окон и сбрасываем Z-порядок окна при обработке сообщения WM_TIMER.

Пример кода

 LRESULT CALLBACK MdiWndProc (HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
static HWND hWndAlwaysOnTop = 0;
switch (message)
{
case WM_CREATE :
SetTimer (hWnd, 1, 200, NULL);
if (!hWndAlwaysOnTop)
{
SetWindowText (hWnd, "Always On Top Window");
hWndAlwaysOnTop = hWnd;
}
break;
case WM_TIMER :
if (hWndAlwaysOnTop)
{
SetWindowPos (hWndAlwaysOnTop, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
break;
case WM_DESTROY:
KillTimer (hWnd, 1) ;
break;
//
// Здесь обрабатываются остальные сообщения.
//
case WM_CLOSE :
if (hWndAlwaysOnTop == hWnd)
hWndAlwaysOnTop = NULL;
default :
return DefMDIChildProc (hWnd, message, wParam, lParam);
}
return 0L;
}  
 
« Предыдущая статья   Следующая статья »