--- /dev/null
+////////////////////////////////////////////////////\r
+// Mainfrm.cpp - definitions for the CMainFrame class\r
+\r
+#include "stdafx.h"\r
+#include "mainfrm.h"\r
+#include "resource.h"\r
+\r
+\r
+CMainFrame::CMainFrame()\r
+{\r
+ // Set m_View as the view window of the frame\r
+ SetView(m_View);\r
+\r
+ // Set the registry key name, and load the initial window position\r
+ // Use a registry key name like "CompanyName\\Application"\r
+ LoadRegistrySettings(_T("Win32++\\Scribble Sample"));\r
+\r
+ // Load the settings from the registry with 4 MRU entries\r
+ LoadRegistryMRUSettings(4);\r
+}\r
+\r
+CMainFrame::~CMainFrame()\r
+{\r
+}\r
+\r
+BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)\r
+{\r
+ // Process the messages from the Menu and Tool Bar\r
+\r
+ UNREFERENCED_PARAMETER(lParam);\r
+\r
+ switch (LOWORD(wParam))\r
+ {\r
+ case IDM_FILE_NEW:\r
+ m_View.ClearPoints();\r
+ m_strPathName = _T("");\r
+ return TRUE;\r
+ case IDM_FILE_OPEN:\r
+ OnFileOpen();\r
+ return TRUE;\r
+ case IDM_FILE_SAVE:\r
+ OnFileSave();\r
+ return TRUE;\r
+ case IDM_FILE_SAVEAS:\r
+ OnFileSaveAs();\r
+ return TRUE;\r
+ case IDM_FILE_PRINT:\r
+ OnFilePrint();\r
+ return TRUE;\r
+ case IDM_PEN_RED:\r
+ TRACE(_T("Red pen selected\n"));\r
+ m_View.SetPen(RGB(255,0,0));\r
+ return TRUE;\r
+ case IDM_PEN_BLUE:\r
+ TRACE(_T("Blue pen selected\n"));\r
+ m_View.SetPen(RGB(0,0,255));\r
+ return TRUE;\r
+ case IDM_PEN_GREEN:\r
+ TRACE(_T("Green pen selected\n"));\r
+ m_View.SetPen(RGB(0,196,0));\r
+ return TRUE;\r
+ case IDM_PEN_BLACK:\r
+ TRACE(_T("Black pen selected\n"));\r
+ m_View.SetPen(RGB(0,0,0));\r
+ return TRUE;\r
+ case IDW_VIEW_STATUSBAR:\r
+ OnViewStatusBar();\r
+ return TRUE;\r
+ case IDW_VIEW_TOOLBAR:\r
+ OnViewToolBar();\r
+ return TRUE;\r
+ case IDM_HELP_ABOUT:\r
+ OnHelp();\r
+ return TRUE;\r
+ case IDM_FILE_EXIT:\r
+ ::PostMessage(m_hWnd, WM_CLOSE, 0, 0);\r
+ return TRUE;\r
+ case IDW_FILE_MRU_FILE1:\r
+ case IDW_FILE_MRU_FILE2:\r
+ case IDW_FILE_MRU_FILE3:\r
+ case IDW_FILE_MRU_FILE4:\r
+ case IDW_FILE_MRU_FILE5:\r
+ {\r
+ UINT nMRUIndex = LOWORD(wParam) - IDW_FILE_MRU_FILE1;\r
+ CString strMRUText = GetMRUEntry(nMRUIndex);\r
+\r
+ if (m_View.FileOpen(strMRUText))\r
+ m_strPathName = strMRUText;\r
+ else\r
+ RemoveMRUEntry(strMRUText);\r
+\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+void CMainFrame::OnFileOpen()\r
+{\r
+ CFile File;\r
+ CString str = File.OpenFileDialog(0, OFN_FILEMUSTEXIST, _T("Scribble Files (*.dat)\0*.dat\0\0"), this);\r
+\r
+ if (!str.IsEmpty())\r
+ {\r
+ // Retrieve the PlotPoint data\r
+ if (m_View.FileOpen(str))\r
+ {\r
+ // Save the filename\r
+ m_strPathName = str;\r
+ AddMRUEntry(str);\r
+ }\r
+ else\r
+ m_strPathName=_T("");\r
+ }\r
+}\r
+\r
+void CMainFrame::OnFileSave()\r
+{\r
+ if (m_strPathName == _T(""))\r
+ OnFileSaveAs();\r
+ else\r
+ m_View.FileSave(m_strPathName);\r
+}\r
+\r
+void CMainFrame::OnFileSaveAs()\r
+{\r
+ CFile File;\r
+ CString str = File.SaveFileDialog(0, OFN_OVERWRITEPROMPT, _T("Scribble Files (*.dat)\0*.dat\0\0"), _T("dat"), this);\r
+\r
+ // Store the PlotPoint data in the file\r
+ if (!str.IsEmpty())\r
+ {\r
+ m_strPathName = str;\r
+\r
+ // Save the file name\r
+ m_View.FileSave(str);\r
+ AddMRUEntry(str);\r
+ }\r
+}\r
+\r
+// Sends the bitmap extracted from the View window to a printer of your choice\r
+// This function provides a useful reference for printing bitmaps in general\r
+void CMainFrame::OnFilePrint()\r
+{\r
+ // Get the dimensions of the View window\r
+ CRect rcView = m_View.GetClientRect();\r
+ int Width = rcView.Width();\r
+ int Height = rcView.Height();\r
+\r
+ // Copy the bitmap from the View window\r
+ CClientDC ViewDC(&m_View);\r
+ CMemDC MemDC(&ViewDC);\r
+ CBitmap bmView;\r
+ bmView.CreateCompatibleBitmap(&ViewDC, Width, Height);\r
+ MemDC.SelectObject(&bmView);\r
+ BitBlt(MemDC, 0, 0, Width, Height, ViewDC, 0, 0, SRCCOPY);\r
+\r
+ // Bring up a dialog to choose the printer\r
+ PRINTDLG pd = {0};\r
+ pd.lStructSize = sizeof( pd );\r
+ pd.Flags = PD_RETURNDC;\r
+ pd.hwndOwner = m_hWnd;\r
+\r
+ // Retrieve the printer DC\r
+ if( !PrintDlg( &pd ) )\r
+ {\r
+ TRACE(_T("PrintDlg canceled"));\r
+ return;\r
+ }\r
+\r
+ // Zero and then initialize the members of a DOCINFO structure.\r
+ DOCINFO di;\r
+ memset( &di, 0, sizeof(DOCINFO) );\r
+ di.cbSize = sizeof(DOCINFO);\r
+ di.lpszDocName = _T("Scribble Printout");\r
+ di.lpszOutput = (LPTSTR) NULL;\r
+ di.lpszDatatype = (LPTSTR) NULL;\r
+ di.fwType = 0;\r
+\r
+ // Begin a print job by calling the StartDoc function.\r
+ if (SP_ERROR == StartDoc(pd.hDC, &di))\r
+ throw CWinException(_T("Failed to start print job"));\r
+\r
+ // Inform the driver that the application is about to begin sending data.\r
+ if (0 > StartPage(pd.hDC))\r
+ throw CWinException(_T("StartPage failed"));\r
+\r
+ BITMAPINFOHEADER bi = {0};\r
+ bi.biSize = sizeof(BITMAPINFOHEADER);\r
+ bi.biHeight = Height;\r
+ bi.biWidth = Width;\r
+ bi.biPlanes = 1;\r
+ bi.biBitCount = 24;\r
+ bi.biCompression = BI_RGB;\r
+\r
+ // Note: BITMAPINFO and BITMAPINFOHEADER are the same for 24 bit bitmaps\r
+ // Get the size of the image data\r
+ MemDC.GetDIBits(&bmView, 0, Height, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS);\r
+\r
+ // Retrieve the image data\r
+ std::vector<byte> vBits(bi.biSizeImage, 0); // a vector to hold the byte array\r
+ byte* pByteArray = &vBits.front();\r
+ MemDC.GetDIBits(&bmView, 0, Height, pByteArray, (BITMAPINFO*)&bi, DIB_RGB_COLORS);\r
+\r
+ // Determine the scaling factors required to print the bitmap and retain its original proportions.\r
+ float fLogPelsX1 = (float) ViewDC.GetDeviceCaps(LOGPIXELSX);\r
+ float fLogPelsY1 = (float) ViewDC.GetDeviceCaps(LOGPIXELSY);\r
+ float fLogPelsX2 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSX);\r
+ float fLogPelsY2 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSY);\r
+ float fScaleX = MAX(fLogPelsX1, fLogPelsX2) / MIN(fLogPelsX1, fLogPelsX2);\r
+ float fScaleY = MAX(fLogPelsY1, fLogPelsY2) / MIN(fLogPelsY1, fLogPelsY2);\r
+\r
+ // Compute the coordinates of the upper left corner of the centered bitmap.\r
+ int cWidthPels = GetDeviceCaps(pd.hDC, HORZRES);\r
+ int xLeft = ((cWidthPels / 2) - ((int) (((float) Width) * fScaleX)) / 2);\r
+ int cHeightPels = GetDeviceCaps(pd.hDC, VERTRES);\r
+ int yTop = ((cHeightPels / 2) - ((int) (((float) Height) * fScaleY)) / 2);\r
+\r
+ // Use StretchDIBits to scale the bitmap and maintain its original proportions\r
+ if (GDI_ERROR == (UINT)StretchDIBits(pd.hDC, xLeft, yTop, (int) ((float) Width * fScaleX),\r
+ (int) ((float) Height * fScaleY), 0, 0, Width, Height, pByteArray, (BITMAPINFO*)&bi, DIB_RGB_COLORS, SRCCOPY))\r
+ {\r
+ throw CWinException(_T("Failed to resize image for printing"));\r
+ }\r
+\r
+ // Inform the driver that the page is finished.\r
+ if (0 > EndPage(pd.hDC))\r
+ throw CWinException(_T("EndPage failed"));\r
+\r
+ // Inform the driver that document has ended.\r
+ if(0 > EndDoc(pd.hDC))\r
+ throw CWinException(_T("EndDoc failed"));\r
+}\r
+\r
+void CMainFrame::OnInitialUpdate()\r
+{\r
+ // Here we process the command line arguments, and automatically load a file if one is specified.\r
+ // GetCommandLineW retrieves our command line arguments.\r
+ // CommandLineToArgvW parses the command line arguements in to an array of strings\r
+ // The first string (lpArgv[0]) contains the name of our program\r
+ // The second string (lpArg[1]) contains an additional parameter (presumably a filename to load).\r
+ // CommandLineToArgvW is not supported in Win95, Win98 or WinME\r
+\r
+\r
+ // CommandLineToArgvW might not be supported, so use run-time dynamic linking to call the function\r
+ HMODULE hMod = LoadLibrary(_T("Shell32.dll"));\r
+ if (hMod)\r
+ {\r
+ // Get a pointer to the CommandLineToArgvW function\r
+ LPWSTR* (WINAPI* fpGetCommandLineW)(LPCWSTR, int*);\r
+ fpGetCommandLineW = (LPWSTR* (WINAPI*)(LPCWSTR, int*))::GetProcAddress(hMod, "CommandLineToArgvW");\r
+\r
+ if (fpGetCommandLineW)\r
+ {\r
+ int argCount = 0;\r
+ LPWSTR* lpArgv = (*fpGetCommandLineW)(::GetCommandLineW(), &argCount);\r
+\r
+ // The second argument (if any) contains our file name.\r
+ if (argCount >= 2)\r
+ {\r
+ m_View.FileOpen((W2T(lpArgv[1])));\r
+ }\r
+\r
+ LocalFree(lpArgv);\r
+ }\r
+\r
+ FreeLibrary(hMod);\r
+ } \r
+\r
+/* \r
+ // This works on Win2000 and above\r
+ int argCount = 0;\r
+ LPWSTR* lpArgv = ::CommandLineToArgvW(::GetCommandLineW(), &argCount);\r
+\r
+ // The second argument (if any) contains our file name.\r
+ if (argCount >= 2)\r
+ {\r
+ m_View.FileOpen((W2T(lpArgv[1])));\r
+ }\r
+*/\r
+}\r
+\r
+void CMainFrame::SetupToolBar()\r
+{\r
+ // Define our toolbar\r
+ AddToolBarButton( IDM_FILE_NEW );\r
+ AddToolBarButton( IDM_FILE_OPEN );\r
+ AddToolBarButton( IDM_FILE_SAVE );\r
+ AddToolBarButton( 0 ); // Separator\r
+ AddToolBarButton( IDM_EDIT_CUT, FALSE );\r
+ AddToolBarButton( IDM_EDIT_COPY, FALSE );\r
+ AddToolBarButton( IDM_EDIT_PASTE, FALSE );\r
+ AddToolBarButton( IDM_FILE_PRINT );\r
+ AddToolBarButton( 0 ); // Separator\r
+ AddToolBarButton( IDM_PEN_RED );\r
+ AddToolBarButton( IDM_PEN_BLUE );\r
+ AddToolBarButton( IDM_PEN_GREEN );\r
+ AddToolBarButton( IDM_PEN_BLACK );\r
+ AddToolBarButton( 0 ); // Separator\r
+ AddToolBarButton( IDM_HELP_ABOUT );\r
+}\r
+\r
+LRESULT CMainFrame::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+// switch (uMsg)\r
+// {\r
+\r
+// } // switch (uMsg)\r
+\r
+ return WndProcDefault(uMsg, wParam, lParam);\r
+} // LRESULT CMainFrame::WndProc(...)\r
+\r