Проблема в том, что не существует стилей для того, чтобы вновь создаваемое 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; } |