📄 cclient.cpp
字号:
m_cDoc++;
/*
* Add this document to the end of our list. This list is
* maintained strictly in the order of creation.
*/
SendMessage(m_hListDocs, LB_ADDSTRING, 0, (LONG)pDoc);
//Update menus and gizmos for the new document if visible
if (fVisible)
m_pFR->UpdateToolbar();
return pDoc;
}
/*
* CClient::ActiveDocument
*
* Purpose:
* Returns the active document window (encapsulates WM_MDIGETACTIVE)
*
* Parameters:
* None
*
* Return Value:
* PCDocument Pointer to the active document object.
*/
PCDocument CClient::ActiveDocument(void)
{
PCDocument pDoc=NULL;
HWND hWnd;
hWnd=(HWND)(UINT)SendMessage(m_hWnd, WM_MDIGETACTIVE, 0, 0L);
if (NULL!=hWnd)
pDoc=(PCDocument)SendMessage(hWnd, DOCM_PDOCUMENT, 0, 0L);
else
pDoc=m_pDocLast;
return pDoc;
}
/*
* CClient::ShowDocument
*
* Purpose:
* Shows or hides a document.
*
* Parameters:
* pDoc PCDocument to show or hide.
* fShow BOOL indicating whether to show or hide the
* document.
*
* Return Value:
* BOOL Previous shown state of the document.
*/
BOOL CClient::ShowDocument(PCDocument pDoc, BOOL fShow)
{
BOOL fRet;
if (NULL==pDoc)
return FALSE;
fRet=IsWindowVisible(pDoc->Window());
ShowWindow(pDoc->Window(), fShow ? SW_SHOW : SW_HIDE);
MDIREFRESHMENU(m_hWnd); //Macro in book1632.h
DrawMenuBar(m_pFR->Window());
SendMessage(m_hWnd, WM_MDIACTIVATE, (WPARAM)pDoc->Window(), 0L);
//Update toolbar if we're changing a document's visibility
if (fShow != fRet)
m_pFR->UpdateToolbar();
return fRet;
}
/*
* CClient::SDIVerify
*
* Purpose:
* In MDI, this is a NOP, but in SDI checks if the user has dirtied
* and wants to save the current document before blasting it away.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the operation calling us can proceed,
* FALSE to abort the operation.
*/
BOOL CClient::SDIVerify(void)
{
#ifdef MDI
return TRUE;
#else
PCDocument pDoc;
pDoc=ActiveDocument();
/*
* In SDI, we'll erase the current, so verify if we have one
* before continuing. If we don't have any document, then we
* don't have a problem.
*/
if (NULL==pDoc)
return TRUE;
return FCleanVerify(pDoc);
#endif
}
/*
* CClient::CloseDocument
*
* Purpose:
* Closes a document created with NewDocument.
*
* Parameters:
* pDoc PCDocument of the document to close.
*
* Return Value:
* UINT New count of open documents.
*/
UINT CClient::CloseDocument(PCDocument pDoc)
{
HWND hWndT;
UINT i;
if (NULL==pDoc)
return m_cDoc;
/*
* Again, since the client window controlled document creation
* we destroy the document window here instead of asking the
* document to do it for us. Once we're rid of the window then
* we can use the destructor.
*/
hWndT=pDoc->Window();
//Don't delete unowned windows.
if (GetParent(hWndT)!=m_hWnd)
return m_cDoc;
//Remove this document from our list.
for (i=0; i < m_cDoc; i++)
{
PCDocument pDocTemp;
if (LB_ERR==SendMessage(m_hListDocs, LB_GETTEXT
, i, (LONG)&pDocTemp))
continue;
if (pDoc==pDocTemp)
SendMessage(m_hListDocs, LB_DELETESTRING, i, 0L);
}
m_cDoc--;
//Update window text. Maxed MDI windows handled automatically.
#ifdef MDI
m_pFR->WindowTitleSet(NULL, TRUE);
#else
m_pFR->WindowTitleSet(NULL, FALSE);
#endif
if (m_pDocLast==pDoc)
m_pDocLast=NULL;
//Let the document clean up first, then we can nuke the window.
SendMessage(m_hWnd, WM_MDIDESTROY, (WPARAM)hWndT, 0L);
delete pDoc;
return m_cDoc;
}
/*
* CClient::QueryCloseAllDocuments
*
* Purpose:
* Ask every document window we have in us if we can close them
* down. We use this when exiting the entire application.
*
* Parameters:
* fClose BOOL indicating if we should query close on the
* documents or acutally close them.
* fSaveChanges BOOL indicating if we should prompt for saving
* changes before closing.
*
* Return Value:
* BOOL TRUE if we can close, FALSE otherwise.
*/
BOOL CClient::QueryCloseAllDocuments(BOOL fClose, BOOL fSaveChanges)
{
UINT i;
UINT cDoc;
PCDocument pDoc;
cDoc=(UINT)SendMessage(m_hListDocs, LB_GETCOUNT, 0, 0L);
for (i=0; i < cDoc; i++)
{
if (LB_ERR!=SendMessage(m_hListDocs, LB_GETTEXT, 0
, (LONG)&pDoc))
{
if (fClose)
{
if (fSaveChanges)
{
if (!FCleanVerify(pDoc))
return FALSE;
}
CloseDocument (pDoc);
}
else
{
if (!(BOOL)SendMessage(pDoc->Window(), WM_QUERYENDSESSION
, 0, 0))
return FALSE;
}
}
}
return TRUE;
}
/*
* CClient::FCleanVerify
*
* Purpose:
* Checks if the document under scrutiny is dirty or not. If so,
* then we ask the user if they want to save it. If not, then we
* just return TRUE. Note that a hidden document is always considered
* clean.
*
* Parameters:
* pDoc PCDocument under consideration.
*
* Return Value:
* BOOL TRUE if the document is clean, saved, or the user
* doesn't want to save it. FALSE if the user
* presses Cancel or the document was not saved.
*/
BOOL CClient::FCleanVerify(PCDocument pDoc)
{
TCHAR szFile[CCHPATHMAX];
LPTSTR psz=szFile;
if (NULL==pDoc)
return TRUE;
if (!IsWindowVisible(pDoc->Window()))
return TRUE;
//Nothing to do if we're clean.
if (!pDoc->FDirtyGet())
return TRUE;
//Get the filename and send to the frame for asking the question.
*psz=0;
pDoc->FilenameGet(psz, CCHPATHMAX);
return m_pFR->AskAndSave(psz);
}
/*
* SDIClientWndProc
*
* Purpose:
* SDI client window class that will create one document for us,
* emulating the functions of an MDI client but with only one doc.
*/
LRESULT APIENTRY SDIClientWndProc(HWND hWnd, UINT iMsg
, WPARAM wParam, LPARAM lParam)
{
HWND hWndDoc;
LPMDICREATESTRUCT pMCS;
RECT rc;
hWndDoc=(HWND)GetWindowLong(hWnd, CLIENTWL_HWNDDOC);
switch (iMsg)
{
case WM_CREATE:
SetWindowLong(hWnd, CLIENTWL_HWNDDOC, 0L);
break;
case WM_SIZE:
if (NULL!=hWndDoc)
{
//Change the document window to match
SetWindowPos(hWndDoc, NULL, 0, 0, LOWORD(lParam)
, HIWORD(lParam), SWP_NOMOVE | SWP_NOZORDER
| SWP_NOACTIVATE);
}
break;
case WM_MDICREATE:
pMCS=(LPMDICREATESTRUCT)lParam;
//We only ate one *visible* document in SDI cases.
if (NULL!=hWndDoc && (WS_VISIBLE & pMCS->style))
return (LONG)(UINT)hWndDoc;
/*
* For our one visible window, we set this as the active
* window. For hidden windows, we return their window
* handle but don't change the 'active' window we store.
*
* Note that we force SDI documents to fill the client
* area.
*/
GetClientRect(hWnd, &rc);
hWndDoc=CreateWindowEx(WS_EX_NOPARENTNOTIFY
, pMCS->szClass, pMCS->szTitle, pMCS->style
, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top
, hWnd, (HMENU)ID_DOCUMENT, (HINSTANCE)pMCS->hOwner
, pMCS);
if (WS_VISIBLE & pMCS->style)
{
ShowWindow(hWndDoc, SW_SHOW);
SetWindowLong(hWnd, CLIENTWL_HWNDDOC
, (LONG)(UINT)hWndDoc);
}
return (LONG)(UINT)hWndDoc;
case WM_MDIACTIVATE:
/*
* Make the new window the active one. The NEWMDIACTIVE
* macro is wParam in Win16, lParam in Win32.
*/
SetWindowLong(hWnd, CLIENTWL_HWNDDOC,(LONG)NEWMDIACTIVE);
break;
case WM_MDIGETACTIVE:
return (LONG)(UINT)hWndDoc;
case WM_MDIDESTROY:
//The only windows we should destroy are children of us.
if (GetParent((HWND)wParam)==hWnd)
{
DestroyWindow((HWND)wParam);
/*
* If this is the visible window, clear out the
* window word.
*/
if ((HWND)wParam==hWndDoc)
SetWindowLong(hWnd, CLIENTWL_HWNDDOC, 0L);
}
break;
default:
return DefWindowProc(hWnd, iMsg, wParam, lParam);
}
return 0L;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -