Как сохранить 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;
}
|