📄 interact.cxx
字号:
if (_hWnd == NULL) {
if (PThread::Current() == owner)
((PInteractor*)this)->CreateHWND();
else {
// All windows must be created in the main thread, so go to stupid
// lengths to make sure it happens
owner->windowsMutex.Wait();
owner->delayedCreateInteractors.Append((PInteractor*)this);
owner->windowsMutex.Signal();
// Post a message to unblock the main loop, so can process above.
::PostThreadMessage(owner->GetThreadId(), WM_USER, 0, 0);
// Wait for main loop thread to do the job.
owner->delayedCreateInteractorsDone.Wait();
}
}
if (_hWnd != NULL && _hWnd != P_DEAD_WINDOW)
return _hWnd;
PAssertAlways(PInvalidWindow);
return NULL;
}
void PInteractor::CreateHWND()
{
PAssert(parent != NULL ||
IsDescendant(PTopLevelWindow::Class()), "Window has no parent");
HINSTANCE hInst = owner->GetInstance();
WNDCLASS wclass;
GetCreateWinInfo(wclass);
if (!GetClassInfo(hInst, wclass.lpszClassName, &wclass))
PAssertOS(RegisterClass(&wclass));
_hWnd = CreateWindowEx(_exStyleBits, wclass.lpszClassName, "", _styleBits,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
parent != NULL ? parent->GetHWND() : NULL,
NULL, hInst, NULL);
owner->AddWindowHandle(PAssertNULL(_hWnd), this);
SetWndFont();
}
PString PInteractor::GetWndText(UINT lenMsg,
UINT getMsg,WPARAM wParamGet, WPARAM wParamLen) const
{
PString title;
HWND hWnd = GetHWND();
UINT len = (UINT)SendMessage(hWnd, lenMsg, wParamLen, 0L)+1;
if (len < sizeof(UINT))
len = sizeof(UINT);
char * ptr = title.GetPointer(len);
if (wParamGet == (WPARAM)-1)
wParamGet = len;
else
*(UINT *)ptr = len;
SendMessage(hWnd, getMsg, wParamGet, (DWORD)(LPSTR)ptr);
PINDEX pos;
while ((pos = title.Find("\r\n")) != P_MAX_INDEX)
title.Delete(pos, 1);
return title;
}
//////////////////////////////////////////////////////////////////////////////
PTitledWindow::PTitledWindow(PInteractor * par, unsigned CanDo)
: PInteractor(par),
icon(PSTD_ID_ICON_WINDOW)
{
focusInteractor = this;
initFlags = CanDo;
}
PTitledWindow::PTitledWindow(unsigned CanDo)
: icon(PSTD_ID_ICON_WINDOW)
{
focusInteractor = this;
initFlags = CanDo;
}
void PTitledWindow::GetCreateWinInfo(WNDCLASS & wndClass)
{
PInteractor::GetCreateWinInfo(wndClass);
if ((initFlags&CanClose) == 0)
wndClass.style |= CS_NOCLOSE;
wndClass.hIcon = icon.GetHICON();
if ((initFlags&CanGrow) != 0)
_styleBits |= WS_THICKFRAME;
if ((initFlags&CanIconify) != 0)
_styleBits |= WS_MINIMIZEBOX;
if ((initFlags&CanZoom) != 0)
_styleBits |= WS_MAXIMIZEBOX;
_styleBits |= WS_CAPTION|WS_SYSMENU;
}
void PTitledWindow::WndProc()
{
switch (_msg->event) {
case WM_CLOSE :
Close();
return;
case WM_DESTROY :
OnClose();
break;
case WM_SETFOCUS :
if (GetFocusInteractor() != this) {
GetFocusInteractor()->GrabFocus();
DefWndProc();
return;
}
break;
case WM_NCACTIVATE :
if (_msg->wParam == FALSE && owner->balloon != NULL) {
_msg->lResult = 0;
return;
}
break;
case WM_ACTIVATE :
OnActivate(LOWORD(_msg->wParam) != WA_INACTIVE);
break;
case WM_MDIACTIVATE :
OnActivate((HWND)(UINT)_msg->lParam == _hWnd);
break;
case WM_MOVE :
OnReposition(PPoint(_msg->lParam));
break;
case WM_SIZE :
if (IsWindowVisible(_hWnd))
OnResize(PDim::FromDWORD(_msg->lParam),
_msg->wParam == SIZE_MINIMIZED ? Iconic :
_msg->wParam == SIZE_MAXIMIZED ? Zoomed : Normalised);
break;
case WM_GETMINMAXINFO :
MINMAXINFO * mmi = (MINMAXINFO *)_msg->lParam;
PRect client;
GetClientRect(GetHWND(), client);
PRect structure = client;
AdjustWindowRectEx(structure, _styleBits,
IsDescendant(PTopLevelWindow::Class()) &&
((PTopLevelWindow *)this)->GetMenu() != NULL,
_exStyleBits);
PDim adjust = structure.Dimensions() - client.Dimensions();
if (minSize.Width() != 0 && minSize.Height() != 0) {
mmi->ptMinTrackSize.x = minSize.Width() + adjust.Width();
mmi->ptMinTrackSize.y = minSize.Height() + adjust.Height();
}
if (maxSize.Width() != 0 && maxSize.Height() != 0) {
mmi->ptMaxTrackSize.x = maxSize.Width() + adjust.Width();
mmi->ptMaxTrackSize.y = maxSize.Height() + adjust.Height();
}
if (zoomSize.Width() != 0 && zoomSize.Height() != 0) {
mmi->ptMaxSize.x = zoomSize.Width() + adjust.Width();
mmi->ptMaxSize.y = zoomSize.Height() + adjust.Height();
}
break;
}
PInteractor::WndProc();
}
void PTitledWindow::SetMinSize(const PDim & dim, CoordinateSystem coords)
{
if (coords != LocalCoords)
minSize = dim;
else
minSize = ToPixels(dim);
SetDimensions(GetDimensions(PixelCoords), PixelCoords);
}
void PTitledWindow::SetMaxSize(const PDim & dim, CoordinateSystem coords)
{
if (coords != LocalCoords)
maxSize = dim;
else
maxSize = ToPixels(dim);
SetDimensions(GetDimensions(PixelCoords), PixelCoords);
}
void PTitledWindow::SetIcon(const PIcon & icn)
{
PSET_CLASS_VALUE(GetHWND(), HICON, icn.GetHICON());
icon = icn;
}
PTitledWindow::ResizeType PTitledWindow::GetSizeMode() const
{
if (IsIconic(GetHWND()))
return Iconic;
if (IsZoomed(GetHWND()))
return Zoomed;
return Normalised;
}
void PTitledWindow::OnReposition(const PPoint &)
{
DefWndProc();
}
void PTitledWindow::OnActivate(BOOL)
{
DefWndProc();
}
void PTitledWindow::OnResize(const PDim &, ResizeType)
{
DefWndProc();
}
//////////////////////////////////////////////////////////////////////////////
PTopLevelWindow::PTopLevelWindow(unsigned CanDo)
: PTitledWindow(CanDo),
helpMenu(PResourceString(PSTD_ID_STR_HELP_MENU, "&Help"))
{
menu = NULL;
deleteMenu = FALSE;
if (owner->mainWindow == NULL)
owner->mainWindow = this;
SetTitle(owner->GetName());
SetMenu(NULL);
new PMenuItem(PSTD_ID_MENU_HELP_CONTENTS, helpMenu,
PResourceString(PSTD_ID_STR_HELP_CONTENTS, "&Contents"));
new PMenuItem(PSTD_ID_STR_HELP_SEARCH, helpMenu,
PResourceString(PSTD_ID_STR_HELP_SEARCH, "&Search for Help..."));
new PMenuItem(PSTD_ID_MENU_HELP_ON_HELP, helpMenu,
PResourceString(PSTD_ID_STR_HELP_ON_HELP, "&How to Use Help"));
new PMenuSeparator(helpMenu);
new PMenuItem(PSTD_ID_MENU_ABOUT, helpMenu, owner->GetAboutMenuItemString());
}
PTopLevelWindow::~PTopLevelWindow()
{
if (deleteMenu)
delete menu;
if (owner->mainWindow == this)
owner->mainWindow = NULL;
}
void PTopLevelWindow::WndProc()
{
switch (_msg->event) {
case WM_SYSCOMMAND :
if (_msg->wParam == PSTD_ID_MENU_ABOUT) {
owner->OnAbout();
return;
}
break;
case WM_COMMAND :
switch (_msg->wParam) {
case PSTD_ID_MENU_ABOUT :
owner->OnAbout();
return;
case PSTD_ID_MENU_HELP_CONTENTS :
owner->DoContextHelp(PSTD_ID_HELP_CONTENTS);
return;
case PSTD_ID_MENU_HELP_SEARCH :
owner->DoContextHelp(PSTD_ID_HELP_SEARCH);
return;
case PSTD_ID_MENU_HELP_ON_HELP :
owner->DoContextHelp(PSTD_ID_HELP_ON_HELP);
return;
default :
if (menu != NULL &&
#if defined(_WIN32)
_msg->lParam == 0)
#else
LOWORD(_msg->lParam) == 0)
#endif
{
PMenuItem*item=menu->GetItemFromKey((PRESOURCE_ID)LOWORD(_msg->wParam));
if (item != NULL) {
OnMenuItemSelect(*item);
return;
}
}
}
break;
case WM_INITMENU :
if (_msg->wParam != 0 && menu != NULL) {
OnMenuStartSelect();
return;
}
break;
}
PTitledWindow::WndProc();
}
void PTopLevelWindow::GetCreateWinInfo(WNDCLASS & wndClass)
{
PTitledWindow::GetCreateWinInfo(wndClass);
_styleBits &= ~WS_CHILD;
}
//////////////////////////////////////////////////////////////////////////////
PMDIFrameWindow::PMDIFrameWindow(unsigned CanDo)
: PTopLevelWindow(CanDo),
windowMenu(PResourceString(PSTD_ID_STR_WINDOW_MENU, "&Window"))
{
CLIENTCREATESTRUCT ccs;
ccs.hWindowMenu = windowMenu.GetHMENU();
ccs.idFirstChild = 32000;
mdiClient = CreateWindow("MDICLIENT", "",
WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE|MDIS_ALLCHILDSTYLES,
0, 0, 0, 0, GetHWND(), NULL, owner->GetInstance(), &ccs);
PAssertNULL(mdiClient);
owner->mdiClient = mdiClient;
backgroundColour.FromSYSCOLOR(COLOR_APPWORKSPACE);
new PMenuItem(PSTD_ID_MENU_WINDOW_CASCADE, windowMenu,
PResourceString(PSTD_ID_STR_WINDOW_CASCADE, "&Cascade"));
new PMenuItem(PSTD_ID_MENU_WINDOW_TILE, windowMenu,
PResourceString(PSTD_ID_STR_WINDOW_TILE, "&Tile"));
new PMenuItem(PSTD_ID_MENU_WINDOW_ARRANGE, windowMenu,
PResourceString(PSTD_ID_STR_WINDOW_ARRANGE, "&Arrange Icons"));
}
PMDIDocWindow * PMDIFrameWindow::GetActiveDocument()
{
HWND hChild = (HWND)(UINT)SendMessage(mdiClient, WM_MDIGETACTIVE, 0, 0L);
if (hChild == NULL)
return NULL;
PInteractor * window = owner->GetWindowObject(hChild);
return (PMDIDocWindow *)PAssertNULL(window);
}
void PMDIFrameWindow::SetDocumentArea(const PRect & rect,
CoordinateSystem coords)
{
switch (coords) {
case LocalCoords :
documentArea = ToPixels(rect);
break;
case PixelCoords :
documentArea = rect;
break;
case ScreenCoords :
PPoint origin = rect.Origin();
ClientToScreen(GetHWND(), origin);
documentArea = rect;
documentArea.SetOrigin(origin);
}
PRect r = documentArea;
if (documentArea.IsEmpty())
r = GetDimensions(PixelCoords);
SetWindowPos(mdiClient, HWND_BOTTOM,
r.X(), r.Y(), r.Width(), r.Height(), SWP_NOACTIVATE);
}
void PMDIFrameWindow::WndProc()
{
switch (_msg->event) {
case WM_COMMAND :
switch (_msg->wParam) {
case PSTD_ID_MENU_WINDOW_CASCADE :
CascadeDocuments();
return;
case PSTD_ID_MENU_WINDOW_TILE :
TileDocuments(GetKeyState(VK_SHIFT) < 0);
return;
case PSTD_ID_MENU_WINDOW_ARRANGE :
ArrangeIcons();
return;
}
break;
case WM_SIZE :
PTopLevelWindow::WndProc();
SetDocumentArea(documentArea, PixelCoords);
return;
}
PTopLevelWindow::WndProc();
}
void PMDIFrameWindow::DefWndProc()
{
_msg->lResult = DefFrameProc(_hWnd,
mdiClient, _msg->event, _msg->wParam, _msg->lParam);
}
///////////////////////////////////////////////////////////////////////////////
// PMDIDocWindow
PMDIDocWindow::~PMDIDocWindow()
{
if (_hWnd != NULL && _hWnd != P_DEAD_WINDOW)
SendMessage(((PMDIFrameWindow*)GetParent())->mdiClient,
WM_MDIDESTROY, (WPARAM)_hWnd, 0L);
}
void PMDIDocWindow::CreateHWND()
{
PAssert(parent->IsDescendant(PMDIFrameWindow::Class()), "Bad MDI parent");
HINSTANCE hInst = owner->GetInstance();
WNDCLASS wclass;
MDICREATESTRUCT mcs;
GetCreateWinInfo(wclass);
mcs.style = _styleBits;
mcs.szClass = wclass.lpszClassName;
mcs.szTitle = initialTitle;
mcs.hOwner = hInst;
mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT;
mcs.lParam = 0;
if (!GetClassInfo(hInst, wclass.lpszClassName, &wclass))
PAssertOS(RegisterClass(&wclass));
#if defined(_WIN32)
_hWnd = CreateMDIWindow((LPTSTR)mcs.szClass, (LPTSTR)mcs.szTitle,
mcs.style, mcs.x, mcs.y, mcs.cx, mcs.cy,
((PMDIFrameWindow *)parent)->mdiClient,
hInst, mcs.lParam);
#else
_hWnd = (HWND)(UINT)SendMessage(((PMDIFrameWindow *)parent)->mdiClient,
WM_MDICREATE, 0, (LPARAM)&mcs);
#endif
owner->AddWindowHandle(PAssertNULL(_hWnd), this);
SetWndFont();
}
void PMDIDocWindow::DefWndProc()
{
_msg->lResult = DefMDIChildProc(_hWnd,_msg->event,_msg->wParam,_msg->lParam);
}
void PMDIDocWindow::Show(BOOL visible)
{
ShowWindow(GetHWND(), visible ? SW_SHOW : SW_HIDE);
#if defined(_WIN32)
SendMessage(((PMDIFrameWindow *)parent)->mdiClient,WM_MDIREFRESHMENU, 0, 0L);
#else
SendMessage(((PMDIFrameWindow *)parent)->mdiClient, WM_MDISETMENU, TRUE, 0L);
#endif
PDim dim = GetDimensions(PixelCoords);
PInteractor::_WindowsMessage * oldMsg = _msg;
PInteractor::_WindowsMessage message;
message.event = WM_SIZE;
message.wParam = SIZE_RESTORED;
message.lParam = dim.ToDWORD();
message.lResult = 0;
message.processed = TRUE;
_msg = &message;
OnResize(dim, Normalised);
_msg = oldMsg;
}
void PMDIDocWindow::Activate()
{
if (!IsVisible())
Show();
SendMessage(((PMDIFrameWindow*)parent)->mdiClient,
WM_MDIACTIVATE, (WPARAM)GetHWND(), 0L);
}
void PMDIDocWindow::SetTitle(const PString & title)
{
PTitledWindow::SetTitle(title);
#if defined(_WIN32)
SendMessage(((PMDIFrameWindow *)parent)->mdiClient,WM_MDIREFRESHMENU, 0, 0L);
#else
SendMessage(((PMDIFrameWindow *)parent)->mdiClient, WM_MDISETMENU, TRUE, 0L);
#endif
}
///////////////////////////////////////////////////////////////////////////////
// PPopUp
PPopUp::PPopUp(PInteractor * parent)
: PInteractor(parent)
{
}
void PPopUp::GetCreateWinInfo(WNDCLASS & wndClass)
{
PInteractor::GetCreateWinInfo(wndClass);
wndClass.style = CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS;
_styleBits = WS_POPUP|WS_BORDER|WS_DISABLED;
_exStyleBits |= WS_EX_TOPMOST;
}
void PPopUp::WndProc()
{
switch (_msg->event) {
case WM_SETFOCUS :
case WM_MOUSEMOVE :
return;
}
PInteractor::WndProc();
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -