📄 notedlg.cpp
字号:
// NoteDlg.cpp : implementation of the CNoteDlg class
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "NoteDlg.h"
#include "HiddenWnd.h"
#include "FindNote.h"
CNoteDlg::CNoteDlg(CHiddenWindow * pWnd) : m_pWndParent(pWnd)
{
ATLTRACE(_T("CNoteDlg::CNoteDlg()\n"));
ATLASSERT(pWnd);
m_bAutoDelete = TRUE;
m_hCursor = NULL;
m_clrDlg = m_Note.m_clrBkgnd;
}
CNoteDlg::CNoteDlg(CHiddenWindow * pWnd, const CNote& objNote) : m_pWndParent(pWnd), m_Note(objNote)
{
ATLTRACE(_T("CNoteDlg::CNoteDlg(const CNote& objNote)\n"));
ATLASSERT(pWnd);
m_bAutoDelete = TRUE;
m_hCursor = NULL;
m_clrDlg = m_Note.m_clrBkgnd;
}
CNoteDlg::~CNoteDlg()
{
ATLTRACE(_T("CNoteDlg::~CNoteDlg()\n"));
// Destroy the brush
if (m_brBkgnd.m_hBrush)
m_brBkgnd.DeleteObject();
// Destroy the bitmaps
if (!::DeleteObject(m_hBmpNote))
ATLTRACE(_T("Note bitmap was not destroyed!\n"));
if (!::DeleteObject(m_hBmpClose))
ATLTRACE(_T("Close bitmap was not destroyed!\n"));
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->RemoveMessageFilter(this);
pLoop->RemoveIdleHandler(this);
}
// Override GetDialogProc to provide our own DialogProc
// See "Q202110 PRB: Deleting ATL Dialog Causes Assert in Atlwin.h, Line 2281" in MSDN
WNDPROC CNoteDlg::GetDialogProc()
{
ATLTRACE(_T("CNoteDlg::GetDialogProc()\n"));
return NoteDialogProc;
}
// Our own dialog procedure that is mostly copied from
// CDialogImplBaseT<>::DialogProc() in Atlwin.h.
LRESULT CALLBACK CNoteDlg::NoteDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ATLTRACE(_T("CNoteDlg::NoteDialogProc()\n"));
CNoteDlg * pThis = (CNoteDlg*)hWnd;
// Set a ptr to this message and save the old value.
MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
const MSG* pOldMsg = pThis->m_pCurrentMsg;
pThis->m_pCurrentMsg = &msg;
// Pass to the message map to process.
LRESULT lRes;
BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam,
lParam, lRes, 0);
// If window has been destroyed and this is the last message,
// then delete ourselves.
if (DEFERDELETE == pThis->m_bAutoDelete && pOldMsg == NULL)
{
delete pThis;
return FALSE;
}
// Restore saved value for the current message.
ATLASSERT(pThis->m_pCurrentMsg == &msg);
pThis->m_pCurrentMsg = pOldMsg;
// Set result if message was handled.
if(bRet)
{
switch (uMsg)
{
case WM_COMPAREITEM:
case WM_VKEYTOITEM:
case WM_CHARTOITEM:
case WM_INITDIALOG:
case WM_QUERYDRAGICON:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
return lRes;
break;
}
::SetWindowLong(pThis->m_hWnd, DWL_MSGRESULT, lRes);
return TRUE;
}
if(uMsg == WM_NCDESTROY)
{
// Clear out window handle.
HWND hWnd = pThis->m_hWnd;
pThis->m_hWnd = NULL;
// Clean up after dialog box is destroyed.
pThis->OnFinalMessage(hWnd);
// If we want to automatically delete ourselves...
if (pThis->m_bAutoDelete)
{
// If no outstanding messages to process in call stack,
// m_pCurrentMsg will be NULL so we can delete ourselves.
if (pThis->m_pCurrentMsg == NULL)
delete pThis;
// Else set a flag so we can delete ourselves later.
else
pThis->m_bAutoDelete = DEFERDELETE;
}
}
return FALSE;
}
LRESULT CNoteDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CNoteDlg::OnInitDialog()\n"));
BOOL bRet;
// Create the brush
m_brBkgnd.CreateSolidBrush(m_clrDlg);
// Set the sizing border width/height
m_nSizeFrame = GetSystemMetrics(SM_CXSIZEFRAME);
// Center the dialog on the screen
CenterWindow();
// Retrieve the coordinates of a dialog's client area
CRect rectDlg;
GetClientRect(&rectDlg);
// Subclass the static control displaying current date and time and
// attach it to the CStaticDateTime object
bRet = m_wndStaticDateTime.SubclassWindow(GetDlgItem(IDC_STATIC_TIME));
ATLASSERT(bRet);
// Set the size and position of the control
m_wndStaticDateTime.MoveWindow(5, rectDlg.Height() - 14, rectDlg.Width() / 2, 14);
// Set the current date and time
m_wndStaticDateTime.SetCurrentDateTime(m_Note.m_strTimestamp);
// Set the background color
m_wndStaticDateTime.SetBkgndColor(m_Note.m_clrBkgnd);
// Subclass the bar static control and attach it to the CStaticBar object
bRet = m_wndStaticBar.SubclassWindow(GetDlgItem(IDC_STATIC_BAR));
ATLASSERT(bRet);
// Set the size and position of the control
m_wndStaticBar.MoveWindow(20, 2, rectDlg.Width() - 41, 15);
// Subclass the edit control and attach it to the CNoteEdit object
bRet = m_wndEdit.SubclassWindow(GetDlgItem(IDC_EDIT));
ATLASSERT(bRet);
// Set the edit control's background color
m_wndEdit.SetBackgroundColor(m_Note.m_clrBkgnd);
// Set the edit control's font
m_wndEdit.SetNoteFont(m_Note.m_strFontName, m_Note.m_lFontHeight, m_Note.m_lWeight,
m_Note.m_bItalic);
// Set the edit control's text
m_wndEdit.SetWindowText(m_Note.m_strNoteText.c_str());
// Set the size and position of the control
m_wndEdit.MoveWindow(5, 20, rectDlg.Width() - 10, rectDlg.Height() - 40);
// Create the static control holding the 'Note' bitmap
CRect rectStatic(1, 1, 17, 17);
HWND hWnd = m_wndStaticNote.Create(m_hWnd, rectStatic, NULL,
WS_CHILD|WS_VISIBLE|SS_BITMAP|SS_CENTERIMAGE|SS_NOTIFY);
ATLASSERT(hWnd);
// Create the static control holding the 'Close' bitmap
rectStatic.SetRect(rectDlg.right - 17, 1, rectDlg.right - 1, 17);
hWnd = m_wndStaticClose.Create(m_hWnd, rectStatic, NULL,
WS_CHILD|WS_VISIBLE|SS_BITMAP|SS_CENTERIMAGE|SS_NOTIFY);
ATLASSERT(hWnd);
// Load the 'Note' bitmap from the application's resources
HBITMAP hBmpTemp = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NOTE));
ATLASSERT(hBmpTemp);
// Load the 'Close' bitmap from the application's resources
HBITMAP hBmpTemp1 = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_CLOSE));
ATLASSERT(hBmpTemp1);
// Replace the white background color with the saved or default (yellow) note's color
m_hBmpNote = ReplaceColor(hBmpTemp, WHITE, m_Note.m_clrBkgnd);
ATLASSERT(m_hBmpNote);
// Replace the white background color with the saved or default (yellow) note's color
HBITMAP hBmpTemp2 = ReplaceColor(hBmpTemp1, WHITE, m_Note.m_clrBkgnd);
ATLASSERT(hBmpTemp2);
// Replace the black foreground color with the red color
m_hBmpClose = ReplaceColor(hBmpTemp2, BLACK, RED);
ATLASSERT(m_hBmpClose);
// Delete the original bitmaps
DeleteObject(hBmpTemp);
DeleteObject(hBmpTemp1);
DeleteObject(hBmpTemp2);
// Draw the 'Note' bitmap in the static control
m_wndStaticNote.SetBitmap(m_hBmpNote);
// Draw the 'Close' bitmap in the static control
m_wndStaticClose.SetBitmap(m_hBmpClose);
// Register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
return TRUE;
}
LRESULT CNoteDlg::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CNoteDlg::OnClose()\n"));
CloseDialog(0);
return 0;
}
void CNoteDlg::CloseDialog(int nVal)
{
ATLTRACE(_T("CNoteDlg::CloseDialog()\n"));
// Display a prompt dialog asking an user if a note should be saved
// but only if the text has been modified in the edit control
if (m_wndEdit.GetModify())
{
int nRet = MessageBox(_T("The text in the note has changed.\n\nDo you want to save the changes?"),
_T("StickyNotes"),
MB_YESNOCANCEL|MB_ICONEXCLAMATION);
if (nRet == IDCANCEL) // 'Cancel' button - do not do anything
return;
if (nRet == IDYES) // 'Yes' button - save the note
{
OnSave();
m_wndEdit.SetModify(FALSE);
}
if (nRet == IDNO) // 'No' button - do not save the note
{}
}
// Destroy the Note dialog
DestroyWindow();
}
LRESULT CNoteDlg::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CNoteDlg::OnPaint()\n"));
PAINTSTRUCT ps;
HDC hDC = BeginPaint(&ps);
ATLASSERT(hDC);
CDC cDC;
cDC.Attach(hDC);
HPEN hOldPen, hPenLine;
CRect rectDlg;
GetClientRect(&rectDlg);
// Create a grey pen
hPenLine = ::CreatePen(PS_SOLID, 1, RGB(125, 125, 125));
ATLASSERT(hPenLine);
// Select the new pen into the device context
hOldPen = (HPEN)::SelectObject(hDC, hPenLine);
ATLASSERT(hOldPen);
ATLASSERT(hOldPen != HGDI_ERROR);
// Draw the gripper
cDC.MoveTo(rectDlg.Width() - 15, rectDlg.Height());
cDC.LineTo(rectDlg.Width(), rectDlg.Height() - 15);
cDC.MoveTo(rectDlg.Width() - 11, rectDlg.Height());
cDC.LineTo(rectDlg.Width(), rectDlg.Height() - 11);
cDC.MoveTo(rectDlg.Width() - 7, rectDlg.Height());
cDC.LineTo(rectDlg.Width(), rectDlg.Height() - 7);
cDC.MoveTo(rectDlg.Width() - 3, rectDlg.Height());
cDC.LineTo(rectDlg.Width(), rectDlg.Height() - 3);
// Draw the horisontal line
cDC.MoveTo(5, rectDlg.Height() - 15);
cDC.LineTo(rectDlg.Width() - 5, rectDlg.Height() - 15);
// Clean up
::SelectObject(hDC, hOldPen);
::DeleteObject(hPenLine);
hPenLine = NULL;
cDC.Detach();
EndPaint(&ps);
return 0;
}
LRESULT CNoteDlg::OnDlgColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CNoteDlg::OnDlgColor()\n"));
ATLASSERT(m_brBkgnd.m_hBrush);
// Change the dialog's background color
return (LRESULT)m_brBkgnd.m_hBrush;
}
// Determine the location of the specified point relative to the client area
// of a dialog.
// point - contains the x- and y-coordinates of the cursor.
int CNoteDlg::HitTest(CPoint point)
{
ATLTRACE(_T("CNoteDlg::HitTest()\n"));
CRect rc;
int nRes = HT_NOWHERE;
GetClientRect(&rc);
// Bar rectangle
CRect rcBar(rc.left + 20, 0, rc.right - 20, 20);
if (point.x <= m_nSizeFrame)
{
// Handle top left, bottom left and left sizing
if (point.y <= m_nSizeFrame)
nRes = HT_TOPLEFT;
else if (point.y >= rc.Height() - m_nSizeFrame)
nRes = HT_BOTTOMLEFT;
else
nRes = HT_LEFT;
}
else if (point.x >= rc.Width() - m_nSizeFrame)
{
// Handle top right, bottom right and right sizing
if (point.y <= m_nSizeFrame)
nRes = HT_TOPRIGHT;
else if (point.y <= rc.Height() - m_nSizeFrame)
nRes = HT_RIGHT;
else
nRes = HT_BOTTOMRIGHT;
}
else if (point.y <= m_nSizeFrame)
{
// Handle top sizing
nRes = HT_TOP;
}
else if (point.y >= rc.Height() - m_nSizeFrame)
{
// Handle bottom sizing
nRes = HT_BOTTOM;
}
else if (rcBar.PtInRect(point))
{
// Handle the dialog moving
nRes = HT_BAR;
}
return nRes;
}
LRESULT CNoteDlg::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CNoteDlg::OnMouseMove()\n"));
// Get the coordinates of the cursor
CPoint point((DWORD)lParam);
int nHitCode = HitTest(point);
// Load the appropriate cursor based on the cursor's location
switch (nHitCode)
{
case HT_TOP:
case HT_BOTTOM:
m_hCursor = ::LoadCursor(NULL, IDC_SIZENS);
break;
case HT_LEFT:
case HT_RIGHT:
m_hCursor = ::LoadCursor(NULL, IDC_SIZEWE);
break;
case HT_TOPLEFT:
case HT_BOTTOMRIGHT:
m_hCursor = ::LoadCursor(NULL, IDC_SIZENWSE);
break;
case HT_TOPRIGHT:
case HT_BOTTOMLEFT:
m_hCursor = ::LoadCursor(NULL, IDC_SIZENESW);
break;
case HT_NOWHERE:
m_hCursor = ::LoadCursor(NULL, IDC_ARROW);
break;
default:
m_hCursor = ::LoadCursor(NULL, IDC_ARROW);
break;
}
ATLASSERT(m_hCursor);
// Set the cursor shape
::SetCursor(m_hCursor);
return 0;
}
LRESULT CNoteDlg::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE(_T("CNoteDlg::OnLButtonDown()\n"));
// Keep the current cursor shape
if (m_hCursor)
::SetCursor(m_hCursor);
// Get the coordinates of the cursor
CPoint point((DWORD)lParam);
int nHitCode = HitTest(point);
if (nHitCode != HT_NOWHERE)
{
// Resize the window
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -