📄 mainfrm.cpp
字号:
/****************************************************************************
MainFrm.cpp : Implementation file for the CMainFrame class
written by PJ Arends
pja@telus.net
For updates check http://www.codeproject.com/tools/imageviewer.asp
-----------------------------------------------------------------------------
This code is provided as is, with no warranty as to it's suitability or usefulness
in any application in which it may be used.
This code may be used in any way you desire. This file may be redistributed by any
means as long as it is not sold for profit, and providing that this notice and the
author's name are included. Any modifications not made by the original author should
be clearly marked as such to remove any confusion between the original version and
any other versions.
If any bugs are found and fixed, a note to the author explaining the problem and
fix would be nice.
-----------------------------------------------------------------------------
****************************************************************************/
#include "stdafx.h"
#include "ImageViewerApp.h"
#include "MainFrm.h"
#include "ChildFrm.h"
#include "ImageViewerView.h"
#include <set>
#define INPUTQUEUEREADERTIMER 0xFEB11965
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMainFrame
IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_WM_ACTIVATE()
ON_WM_COPYDATA()
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_MESSAGE(WM_SETMESSAGESTRING, &CMainFrame::OnSetMessageString)
ON_MESSAGE(WMU_DOCUMENTCLOSING, &CMainFrame::OnDocumentClosing)
ON_MESSAGE(WMU_GETBGCOLOUR, &CMainFrame::OnGetBGColour)
ON_MESSAGE(WMU_GETDISPLAYLOCK, &CMainFrame::OnGetDisplayLock)
ON_MESSAGE(WMU_UPDATETOOLTIP, &CMainFrame::OnUpdateTooltip)
ON_MESSAGE(WMU_SETPROPERTIES, &CMainFrame::OnSetProperties)
ON_REGISTERED_MESSAGE(RWM_ARE_YOU_ME, &CMainFrame::OnAreYouMe)
ON_COMMAND(ID_VIEW_BACKGROUND_COLOUR, &CMainFrame::OnViewBackgroundColour)
ON_COMMAND(ID_VIEW_HEXADECIMAL_TOOLTIPS, &CMainFrame::OnViewHexadecimalTooltips)
ON_UPDATE_COMMAND_UI(ID_VIEW_HEXADECIMAL_TOOLTIPS, &CMainFrame::OnUpdateViewHexadecimalTooltips)
ON_COMMAND(ID_VIEW_DISPLAY_LOCK, &CMainFrame::OnViewDisplayLock)
ON_UPDATE_COMMAND_UI(ID_VIEW_DISPLAY_LOCK, &CMainFrame::OnUpdateViewDisplayLock)
ON_COMMAND(ID_VIEW_ON_TOP, &CMainFrame::OnViewOnTop)
ON_UPDATE_COMMAND_UI(ID_VIEW_ON_TOP, &CMainFrame::OnUpdateViewOnTop)
ON_COMMAND(ID_IMAGE_PROPERTIES, &CMainFrame::OnImageProperties)
ON_UPDATE_COMMAND_UI(ID_IMAGE_PROPERTIES, &CMainFrame::OnUpdateImageProperties)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_MEM, &CMainFrame::OnUpdateIndicatorMem)
ON_COMMAND(ID_FILE_CLOSEALL, &CMainFrame::OnFileCloseAll)
ON_COMMAND(ID_FILE_CLOSEALLEXCEPTACTIVE, &CMainFrame::OnFileCloseAllExceptActive)
ON_COMMAND(ID_FILE_CLOSEACTIVE, &CMainFrame::OnFileCloseActive)
END_MESSAGE_MAP()
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
: HexTooltip(false)
, DisplayLock(false)
{
BackgroundColour = RGB(192, 192, 192); // default colour
theApp.GetObjectArray(_T("Settings"), _T("Background Colour"), &BackgroundColour); // get saved colour, if any
HexTooltip = theApp.GetProfileInt(_T("Settings"), _T("Hex Tooltips"), 0) != 0;
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndToolBar.LoadTrueColorToolBar(16, IDB_COLOURTOOLBAR, 0, IDB_GRAYTOOLBAR);
if (theApp.GetProfileInt(_T("Settings"), _T("Always on Top"), 0) != 0)
{
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
// move the main window to where it was the last time the app was run
WINDOWPLACEMENT WindowPlacement = {0};
if (ERROR_SUCCESS == theApp.GetObjectArray(_T("Settings"), _T("Main Window Placement"), &WindowPlacement))
{
// bug: Window looses restored settings when it was closed in minimized or maximized state
// fix: http://support.microsoft.com/kb/171375/en-us
// will cause window to flash at restored size before switching to either maximized or minimized size
UINT ShowCommand = WindowPlacement.showCmd;
if (ShowCommand == SW_SHOWMINIMIZED || ShowCommand == SW_SHOWMAXIMIZED)
{
WindowPlacement.showCmd = SW_RESTORE;
}
SetWindowPlacement(&WindowPlacement);
if (ShowCommand == SW_SHOWMINIMIZED || ShowCommand == SW_SHOWMAXIMIZED)
{
PostMessage(WM_SYSCOMMAND, ShowCommand == SW_SHOWMINIMIZED ? SC_MINIMIZE : SC_MAXIMIZE, 0);
}
}
// Create and setup the tooltip
ColourTooltip.Create(this);
ColourTooltip.SetHex(HexTooltip);
// create the image properties dialog
PropertiesDialog.Create(IDD_PROPERTIES, this);
// start the image queue reader timer
SetTimer(INPUTQUEUEREADERTIMER, USER_TIMER_MINIMUM, NULL);
#ifdef DEBUG
CString Text;
GetWindowText(Text);
Text += _T(" - DEBUG");
SetWindowText(Text);
#endif
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~FWS_ADDTOTITLE;
if( !CMDIFrameWnd::PreCreateWindow(cs) )
return FALSE;
return TRUE;
}
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CMDIFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CMDIFrameWnd::Dump(dc);
}
#endif //_DEBUG
// CMainFrame message handlers
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
if (INPUTQUEUEREADERTIMER == nIDEvent && !theApp.InputQueue.empty())
{
CSingleLock SingleLock(&theApp.QueueSection, FALSE);
CImageData ImageData;
int counter = 0;
DWORD ID = 0;
std::set<DWORD> UsedIDs;
// process at most only 50 images at a time in order to keep the app responsive
while (!theApp.InputQueue.empty() && ++counter < 50)
{
if (SingleLock.Lock())
{
// get the next image from the queue
ImageData = theApp.InputQueue.front();
theApp.InputQueue.pop();
SingleLock.Unlock();
}
ID = ImageData.GetProcessID();
if (ID != 0)
{
IDDocMap::iterator it = IDDocs.find(ID);
if (it == IDDocs.end())
{
// Create a document and view for this new process
POSITION pos = theApp.GetFirstDocTemplatePosition();
CDocTemplate *pTemplate = theApp.GetNextDocTemplate(pos);
// if the display lock is on we save the current child frame so we can reactivate it later
CFrameWnd *pActiveFrame = NULL;
if (DisplayLock)
{
pActiveFrame = GetActiveFrame();
}
CImageViewerDoc *pDoc = dynamic_cast<CImageViewerDoc *>(pTemplate->OpenDocumentFile(NULL));
if (DisplayLock && NULL != pActiveFrame)
{
pActiveFrame->ActivateFrame();
}
if (NULL == pDoc)
{
// OpenDocumentFile failed, skip this image and go on to the next one
continue;
}
IDDocs[ID] = pDoc;
pDoc->SetCaption(ID);
if (DisplayLock)
{
// short circuit loop to make sure the first image recieved is displayed
counter = 50;
}
}
IDDocs[ID]->AddImageData(ImageData);
UsedIDs.insert(ID);
}
}
if (!UsedIDs.empty())
{
for (std::set<DWORD>::iterator it = UsedIDs.begin(); it != UsedIDs.end(); ++it)
{
// update the views of the documents that got new images
IDDocs[*it]->UpdateAllViews(NULL, 0xfeb1, NULL);
}
theApp.OnIdle(-1); // force the toolbar to update
}
}
}
LRESULT CMainFrame::OnDocumentClosing(WPARAM ID, LPARAM)
{
// When a document is closed, it sends a WMU_DOCUMENTCLOSING message
// to the mainframe so the mainframe can remove the document ID from
// its map of active documents. See CImageViewerDoc::OnCloseDocument()
return IDDocs.erase(static_cast<DWORD>(ID));
}
void CMainFrame::OnViewBackgroundColour()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -