📄 cwindow.cpp
字号:
void
CWindow::Create(
const char *classNameOrAtom,
WNDPROC superedProc,
const char *windowName,
PGPUInt32 style,
PGPUInt32 exStyle,
PGPInt32 x,
PGPInt32 y,
PGPInt32 width,
PGPInt32 height,
HWND parent,
HMENU menu)
{
pgpAssert(!WeCreated());
pgpAssert(!WeSubclassed());
pgpAssert(IsntNull(classNameOrAtom));
RefWindowMap();
try
{
mWeCreated = TRUE;
mInModal = FALSE;
mSawClose = FALSE;
mPrevWndProc = superedProc;
HWND hWnd = CreateWindowEx(exStyle, classNameOrAtom,
windowName, style, x, y, width, height, parent, menu,
UModuleInstance::Get(), this);
if (IsNull(hWnd))
THROW_ERRORS(kPGPError_Win32WindowOpFailed, GetLastError());
}
catch (CComboError&)
{
mWeCreated = FALSE;
DerefWindowMap();
throw;
}
}
void
CWindow::Close()
{
pgpAssert(WeCreated());
SendMessage(WM_CLOSE); // be nice
}
LRESULT
CWindow::CallDefault()
{
if (IsntNull(mPrevWndProc))
{
if (mWeSubclassedUnicode)
{
return CallWindowProcW(mPrevWndProc, Handle(), CurMsg().Message(),
CurMsg().WParam(), CurMsg().LParam());
}
else
{
return CallWindowProcA(mPrevWndProc, Handle(), CurMsg().Message(),
CurMsg().WParam(), CurMsg().LParam());
}
}
else
{
pgpAssert(WeCreated());
return DefWindowProc(Handle(), CurMsg().Message(),
CurMsg().WParam(), CurMsg().LParam());
}
}
void
CWindow::RefWindowMap()
{
if (mWindowMapRefCount == 0)
{
mWindowMap = new CHashTable<CWindow>(WindowMapSize);
mWindowMapLock = new CRMWOLock;
}
mWindowMapRefCount++;
}
void
CWindow::DerefWindowMap()
{
if ((mWindowMapRefCount > 0) && (--mWindowMapRefCount == 0))
{
delete mWindowMap;
mWindowMap = NULL;
delete mWindowMapLock;
mWindowMapLock = NULL;
}
}
CWindow *
CWindow::HandleToWindow(HWND hWnd)
{
pgpAssert(::IsWindow(hWnd));
CWindow *pWindow;
mWindowMapLock->StartReading();
try
{
pWindow = mWindowMap->Lookup(reinterpret_cast<PGPUInt32>(hWnd));
}
catch (CComboError&)
{
mWindowMapLock->StopReading();
throw;
}
mWindowMapLock->StopReading();
return pWindow;
}
void
CWindow::AssocHandleToWindow(HWND hWnd, CWindow *pWindow)
{
pgpAssert(::IsWindow(hWnd));
pgpAssertAddrValid(pWindow, CWindow);
mWindowMapLock->StartWriting();
try
{
mWindowMap->Add(reinterpret_cast<PGPUInt32>(hWnd), pWindow);
pWindow->mHwnd = hWnd;
}
catch (CComboError&)
{
mWindowMapLock->StopWriting();
throw;
}
mWindowMapLock->StopWriting();
}
void
CWindow::UnAssocHandleFromWindow(HWND hWnd)
{
pgpAssert(::IsWindow(hWnd));
mWindowMapLock->StartWriting();
try
{
mWindowMap->Remove(reinterpret_cast<PGPUInt32>(hWnd));
}
catch (CComboError&)
{
mWindowMapLock->StopWriting();
throw;
}
mWindowMapLock->StopWriting();
}
PGPBoolean
CWindow::DispatchCommon(LRESULT &result)
{
result = 0;
PGPUInt32 message = CurMsg().Message();
WPARAM wParam = CurMsg().WParam();
LPARAM lParam = CurMsg().LParam();
switch (message)
{
case WM_CHAR:
OnChar(static_cast<char>(wParam), lParam);
return TRUE;
case WM_CLEAR:
OnClear();
return TRUE;
case WM_CLOSE:
OnClose();
return TRUE;
case WM_COMMAND:
result = OnCommand(UMath::GetHighWord(wParam),
UMath::GetLowWord(wParam), reinterpret_cast<HWND>(lParam));
return TRUE;
case WM_CONTEXTMENU:
OnContextMenu(reinterpret_cast<HWND>(wParam),
CPoint(UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam)));
return TRUE;
case WM_COPY:
OnCopy();
return TRUE;
case WM_CREATE:
result = OnCreate(reinterpret_cast<LPCREATESTRUCT>(lParam));
return TRUE;
case WM_CTLCOLORSTATIC:
result = reinterpret_cast<LRESULT>(OnCtlColorStatic(
reinterpret_cast<HDC>(wParam), reinterpret_cast<HWND>(lParam)));
return TRUE;
case WM_CUT:
OnCut();
return TRUE;
case WM_DESTROY:
OnDestroy();
return TRUE;
case WM_DRAWITEM:
result = OnDrawItem(wParam,
reinterpret_cast<LPDRAWITEMSTRUCT>(lParam));
return TRUE;
case WM_ERASEBKGND:
result = OnEraseBkgnd(reinterpret_cast<HDC>(wParam));
return TRUE;
case WM_GETMINMAXINFO:
OnGetMinMaxInfo(reinterpret_cast<LPMINMAXINFO>(lParam));
return TRUE;
case WM_HELP:
OnHelp(reinterpret_cast<HELPINFO *>(lParam));
return TRUE;
case WM_INITMENU:
OnInitMenu(reinterpret_cast<HMENU>(wParam));
return TRUE;
case WM_KEYDOWN:
OnKeyDown(wParam, lParam);
return TRUE;
case WM_KEYUP:
OnKeyUp(wParam, lParam);
return TRUE;
case WM_KILLFOCUS:
OnKillFocus();
return TRUE;
case WM_LBUTTONDBLCLK:
OnLButtonDblClk(wParam, CPoint(UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam)));
return TRUE;
case WM_LBUTTONDOWN:
OnLButtonDown(wParam, CPoint(UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam)));
return TRUE;
case WM_LBUTTONUP:
OnLButtonUp(wParam, CPoint(UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam)));
return TRUE;
case WM_MEASUREITEM:
result = OnMeasureItem(wParam,
reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam));
return TRUE;
case WM_MENUSELECT:
OnMenuSelect(UMath::GetLowWord(wParam),
UMath::GetHighWord(wParam), reinterpret_cast<HMENU>(lParam));
return TRUE;
case WM_MOUSEMOVE:
OnMouseMove(wParam, CPoint(UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam)));
return TRUE;
case WM_NCCREATE:
result = OnNcCreate(reinterpret_cast<LPCREATESTRUCT>(lParam));
return TRUE;
case WM_NCDESTROY:
OnNcDestroy();
return TRUE;
case WM_NOTIFY:
result = OnNotify(wParam, reinterpret_cast<LPNMHDR>(lParam));
return TRUE;
case WM_PAINT:
OnPaint(reinterpret_cast<HDC>(wParam));
return TRUE;
case WM_PASTE:
OnPaste();
return TRUE;
case WM_SETFOCUS:
OnSetFocus();
return TRUE;
case WM_SIZE:
OnSize(wParam,
UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam));
return TRUE;
case WM_SYSCOLORCHANGE:
OnSysColorChange();
return TRUE;
case WM_SYSCOMMAND:
result = OnSysCommand(wParam, UMath::GetLowWord(lParam),
UMath::GetHighWord(lParam));
return TRUE;
case WM_TIMER:
OnTimer(wParam, reinterpret_cast<TIMERPROC *>(lParam));
return TRUE;
case WM_UNDO:
result = OnUndo();
return TRUE;
default:
return FALSE;
}
}
LRESULT
CWindow::WindowProc(const CMessage& msg)
{
LRESULT result = 0;
// Save old message.
CMessage oldMsg = mCurMsg;
mCurMsg = msg;
try
{
// See if client wants to handle it.
if (!PreProcess(CurMsg(), result) && !DispatchCommon(result))
result = CallDefault();
PostProcess(CurMsg(), result);
}
catch (CComboError& caughtError)
{
HandleWindowError(caughtError);
result = 0;
}
// Restore old message.
mCurMsg = oldMsg;
return result;
}
LRESULT
CALLBACK
CWindow::GlobalWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
try
{
if (uMsg == WM_NCCREATE)
{
// New window created, map window pointer.
LPCREATESTRUCT pCS = reinterpret_cast<LPCREATESTRUCT>(lParam);
CWindow *pWindow = static_cast<CWindow *>(pCS->lpCreateParams);
pgpAssertAddrValid(pWindow, CWindow);
AssocHandleToWindow(hWnd, pWindow);
if (!pWindow->WindowProc(CMessage(uMsg, wParam, lParam, hWnd)))
{
UnAssocHandleFromWindow(hWnd);
return FALSE;
}
return TRUE;
}
else
{
// Find CWindow pointer corresponding to this HWND.
CWindow *pWindow = HandleToWindow(hWnd);
if (IsNull(pWindow))
return DefWindowProc(hWnd, uMsg, wParam, lParam);
LRESULT result = pWindow->WindowProc(CMessage(uMsg, wParam,
lParam, hWnd));
// Unmap window handle on destruction.
if (uMsg == WM_NCDESTROY)
{
UnAssocHandleFromWindow(hWnd);
DerefWindowMap();
pWindow->mWeCreated = FALSE;
result = 0;
}
return result;
}
}
catch (CComboError&)
{
pgpAssert(FALSE);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
LRESULT
CALLBACK
CWindow::GlobalWindowProcSubclassed(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
try
{
// Find CWindow pointer corresponding to this HWND;
CWindow *pWindow = HandleToWindow(hWnd);
if (IsNull(pWindow))
THROW_PGPERROR(kPGPError_ItemNotFound);
LRESULT result = pWindow->WindowProc(CMessage(uMsg, wParam, lParam,
hWnd));
// Unmap window handle on destruction.
if (uMsg == WM_NCDESTROY)
{
UnAssocHandleFromWindow(hWnd);
pWindow->UnSubclass();
result = 0;
}
return result;
}
catch (CComboError&)
{
pgpAssert(FALSE);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
void
CWindow::OnClose()
{
if (mInModal)
{
mInModal = FALSE;
mSawClose = TRUE;
}
else
{
CallDefault();
}
}
BOOL
CWindow::OnCommand(PGPUInt16 notifyCode, PGPUInt16 itemId, HWND ctrl)
{
// Reflect message to child control.
if (ctrl != Handle())
{
BOOL result = CallDefault();
CWindow ctrlWnd(ctrl);
ctrlWnd.SendMessage(WM_COMMAND, UMath::MakeDWord(itemId,
notifyCode), reinterpret_cast<LPARAM>(ctrl));
return result;
}
else
{
return 0;
}
}
BOOL
CWindow::OnDrawItem(PGPUInt16 ctrlId, LPDRAWITEMSTRUCT pDIS)
{
// Reflect message to child control.
CWindow ctrlWnd(pDIS->hwndItem);
if (!(pDIS->CtlType & ODT_MENU) && (ctrlWnd.Handle() != Handle()))
{
BOOL result = CallDefault();
ctrlWnd.SendMessage(WM_DRAWITEM, ctrlId, reinterpret_cast<LPARAM>(
pDIS));
return result;
}
else
{
return FALSE;
}
}
BOOL
CWindow::OnMeasureItem(PGPUInt16 ctrlId, LPMEASUREITEMSTRUCT pMIS)
{
// Reflect message to child control.
CWindow ctrlWnd(GetDlgItem(ctrlId));
if (!(pMIS->CtlType & ODT_MENU) && (ctrlWnd.Handle() != Handle()))
{
BOOL result = CallDefault();
ctrlWnd.SendMessage(WM_MEASUREITEM, ctrlId,
reinterpret_cast<LPARAM>(pMIS));
return result;
}
else
{
return FALSE;
}
}
PGPUInt32
CWindow::OnNotify(PGPUInt16 ctrlId, LPNMHDR pNMHDR)
{
// Reflect message to child control.
CWindow ctrlWnd(pNMHDR->hwndFrom);
if (ctrlWnd.Handle() != Handle())
{
PGPUInt32 result = CallDefault();
ctrlWnd.SendMessage(WM_NOTIFY, ctrlId, reinterpret_cast<LPARAM>(
pNMHDR));
return result;
}
else
{
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -