1 /////////////////////////////////////////////////
\r
6 #include <richedit.h>
\r
7 #include "resource.h"
\r
10 //For Visual C++ 6 and without a modern SDK
\r
12 #define DWORD_PTR DWORD
\r
16 // definitions for the CMainFrame class
\r
17 CMainFrame::CMainFrame()
\r
19 m_strPathName = _T("");
\r
20 SetView(m_RichView);
\r
22 // Set the registry key name, and load the initial window position
\r
23 // Use a registry key name like "CompanyName\\Application"
\r
24 LoadRegistrySettings(_T("Win32++\\Notepad Sample"));
\r
26 // Load the settings from the registry with 5 MRU entries
\r
27 LoadRegistryMRUSettings(5);
\r
30 CMainFrame::~CMainFrame()
\r
34 void CMainFrame::OnInitialUpdate()
\r
36 DragAcceptFiles(TRUE);
\r
38 m_RichView.SetFocus();
\r
41 LRESULT CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam)
\r
44 pNMH = (LPNMHDR) lParam;
\r
49 ENDROPFILES* ENDrop = (ENDROPFILES*)lParam;
\r
50 HDROP hDropInfo = (HDROP) ENDrop->hDrop;
\r
51 OnDropFiles(hDropInfo);
\r
56 return CFrame::OnNotify(wParam, lParam);
\r
59 BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
\r
61 UNREFERENCED_PARAMETER(lParam);
\r
63 switch (LOWORD(wParam))
\r
74 case IDM_FILE_SAVEAS:
\r
77 case IDM_FILE_PRINT:
\r
83 case IDM_EDIT_PASTE:
\r
89 case IDM_EDIT_DELETE:
\r
99 ::PostMessage(m_hWnd, WM_CLOSE, 0, 0);
\r
101 case IDW_VIEW_STATUSBAR:
\r
104 case IDW_VIEW_TOOLBAR:
\r
107 case IDM_HELP_ABOUT:
\r
110 case IDW_FILE_MRU_FILE1:
\r
111 case IDW_FILE_MRU_FILE2:
\r
112 case IDW_FILE_MRU_FILE3:
\r
113 case IDW_FILE_MRU_FILE4:
\r
114 case IDW_FILE_MRU_FILE5:
\r
116 UINT nMRUIndex = LOWORD(wParam) - IDW_FILE_MRU_FILE1;
\r
117 CString strMRUText = GetMRUEntry(nMRUIndex);
\r
119 if (ReadFile(strMRUText))
\r
120 m_strPathName = strMRUText;
\r
122 RemoveMRUEntry(strMRUText);
\r
131 } // CMainFrame::OnCommand(...)
\r
134 void CMainFrame::OnFileNew()
\r
136 m_RichView.SetWindowText(_T(""));
\r
137 m_strPathName = _T("");
\r
139 m_RichView.SetFontDefaults();
\r
140 m_RichView.SendMessage(EM_SETMODIFY, FALSE, 0);
\r
143 void CMainFrame::OnFilePrint()
\r
147 // Initialize PRINTDLG
\r
148 ZeroMemory(&pd, sizeof(pd));
\r
149 pd.lStructSize = sizeof(pd);
\r
150 pd.hwndOwner = m_hWnd;
\r
151 pd.hDevMode = NULL; // Don't forget to free or store hDevMode
\r
152 pd.hDevNames = NULL; // Don't forget to free or store hDevNames
\r
153 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
\r
155 pd.nFromPage = 0xFFFF;
\r
156 pd.nToPage = 0xFFFF;
\r
158 pd.nMaxPage = 0xFFFF;
\r
159 pd.hwndOwner = m_hWnd;
\r
161 if (PrintDlg(&pd)==TRUE)
\r
163 HDC hPrinterDC = pd.hDC;
\r
165 // This code basically taken from MS KB article Q129860
\r
168 int nHorizRes = ::GetDeviceCaps(hPrinterDC, HORZRES);
\r
169 int nVertRes = ::GetDeviceCaps(hPrinterDC, VERTRES);
\r
170 int nLogPixelsX = ::GetDeviceCaps(hPrinterDC, LOGPIXELSX);
\r
171 int nLogPixelsY = ::GetDeviceCaps(hPrinterDC, LOGPIXELSY);
\r
172 LONG lTextLength; // Length of document.
\r
173 LONG lTextPrinted; // Amount of document printed.
\r
175 // Ensure the printer DC is in MM_TEXT mode.
\r
176 ::SetMapMode ( hPrinterDC, MM_TEXT );
\r
178 // Rendering to the same DC we are measuring.
\r
179 ZeroMemory(&fr, sizeof(fr));
\r
180 fr.hdc = hPrinterDC;
\r
181 fr.hdcTarget = hPrinterDC;
\r
183 // Set up the page.
\r
184 int margin = 200; // 1440 TWIPS = 1 inch.
\r
185 fr.rcPage.left = fr.rcPage.top = margin;
\r
186 fr.rcPage.right = (nHorizRes/nLogPixelsX) * 1440 - margin;
\r
187 fr.rcPage.bottom = (nVertRes/nLogPixelsY) * 1440 - margin;
\r
189 // Set up margins all around.
\r
190 fr.rc.left = fr.rcPage.left ;//+ 1440;
\r
191 fr.rc.top = fr.rcPage.top ;//+ 1440;
\r
192 fr.rc.right = fr.rcPage.right ;//- 1440;
\r
193 fr.rc.bottom = fr.rcPage.bottom ;//- 1440;
\r
195 // Default the range of text to print as the entire document.
\r
197 fr.chrg.cpMax = -1;
\r
198 m_RichView.SendMessage(EM_FORMATRANGE, true, (LPARAM)&fr);
\r
200 // Set up the print job (standard printing stuff here).
\r
202 ZeroMemory(&di, sizeof(di));
\r
203 di.cbSize = sizeof(DOCINFO);
\r
204 di.lpszDocName = m_strPathName;
\r
206 // Do not print to file.
\r
207 di.lpszOutput = NULL;
\r
209 // Start the document.
\r
210 ::StartDoc(hPrinterDC, &di);
\r
211 GETTEXTLENGTHEX tl;
\r
212 tl.flags = GTL_NUMCHARS;
\r
214 // Find out real size of document in characters.
\r
215 lTextLength = (LONG)m_RichView.SendMessage(EM_GETTEXTLENGTHEX, (WPARAM)&tl, 0L);
\r
220 ::StartPage(hPrinterDC);
\r
222 // Print as much text as can fit on a page. The return value is
\r
223 // the index of the first character on the next page. Using TRUE
\r
224 // for the wParam parameter causes the text to be printed.
\r
225 lTextPrinted = (LONG)::SendMessage(m_RichView.GetHwnd(), EM_FORMATRANGE, true, (LPARAM)&fr);
\r
227 m_RichView.SendMessage(EM_DISPLAYBAND, 0, (LPARAM)&fr.rc);
\r
229 // Print last page.
\r
230 ::EndPage(hPrinterDC);
\r
232 // If there is more text to print, adjust the range of characters
\r
233 // to start printing at the first character of the next page.
\r
234 if (lTextPrinted < lTextLength)
\r
236 fr.chrg.cpMin = (LONG)lTextPrinted;
\r
237 fr.chrg.cpMax = -1;
\r
240 while (lTextPrinted < lTextLength);
\r
242 // Tell the control to release cached information.
\r
243 m_RichView.SendMessage(EM_FORMATRANGE, false, 0L);
\r
245 ::EndDoc (hPrinterDC);
\r
247 // Delete DC when done.
\r
248 ::DeleteDC(hPrinterDC);
\r
252 void CMainFrame::OnEditCut()
\r
254 m_RichView.SendMessage(WM_CUT, 0, 0);
\r
256 void CMainFrame::OnEditCopy()
\r
258 m_RichView.SendMessage(WM_COPY, 0, 0);
\r
260 void CMainFrame::OnEditPaste()
\r
262 m_RichView.SendMessage(EM_PASTESPECIAL, CF_TEXT, 0);
\r
264 void CMainFrame::OnEditDelete()
\r
266 m_RichView.SendMessage(WM_CLEAR, 0, 0);
\r
268 void CMainFrame::OnEditRedo()
\r
270 m_RichView.SendMessage(EM_REDO, 0, 0);
\r
272 void CMainFrame::OnEditUndo()
\r
274 m_RichView.SendMessage(EM_UNDO, 0, 0);
\r
277 void CMainFrame::OnClose()
\r
279 //Check for unsaved text
\r
280 BOOL bChanged = (BOOL)m_RichView.SendMessage(EM_GETMODIFY, 0, 0);
\r
282 if (::MessageBox(NULL, _T("Save changes to this document"), _T("TextEdit"), MB_YESNO | MB_ICONWARNING) == IDYES)
\r
288 void CMainFrame::OnDropFiles(HDROP hDropInfo)
\r
290 TCHAR szFileName[_MAX_PATH];
\r
291 ::DragQueryFile((HDROP)hDropInfo, 0, (LPTSTR)szFileName, _MAX_PATH);
\r
293 ReadFile(szFileName);
\r
296 BOOL CMainFrame::ReadFile(LPCTSTR szFileName)
\r
298 // Open the file for reading
\r
300 if (!File.Open(szFileName, OPEN_EXISTING))
\r
302 CString str = _T("Failed to load: ");
\r
304 ::MessageBox(NULL, str, _T("Warning"), MB_ICONWARNING);
\r
308 //Set default font and color
\r
309 m_RichView.SetFontDefaults();
\r
312 es.dwCookie = (DWORD_PTR) File.GetHandle();
\r
313 es.pfnCallback = (EDITSTREAMCALLBACK) MyStreamInCallback;
\r
314 m_RichView.SendMessage(EM_STREAMIN, SF_TEXT, (LPARAM)&es);
\r
316 //Clear the modified text flag
\r
317 m_RichView.SendMessage(EM_SETMODIFY, FALSE, 0);
\r
322 BOOL CMainFrame::WriteFile(LPCTSTR szFileName)
\r
324 // Open the file for writing
\r
326 if (!File.Open(szFileName, CREATE_ALWAYS))
\r
328 CString str = _T("Failed to write: ");
\r
330 ::MessageBox(NULL, str, _T("Warning"), MB_ICONWARNING);
\r
336 es.dwCookie = (DWORD_PTR) File.GetHandle();
\r
338 es.pfnCallback = (EDITSTREAMCALLBACK) MyStreamOutCallback;
\r
340 m_RichView.SendMessage(EM_STREAMOUT, SF_TEXT, (LPARAM)&es);
\r
342 //Clear the modified text flag
\r
343 m_RichView.SendMessage(EM_SETMODIFY, FALSE, 0);
\r
348 void CMainFrame::OnFileOpen()
\r
350 // szFilters is a text string that includes two file name filters:
\r
351 // "*.my" for "MyType Files" and "*.*' for "All Files."
\r
352 CString Filters( _T("Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0"), 46);
\r
354 CString str = File.OpenFileDialog(0, OFN_FILEMUSTEXIST, Filters, this);
\r
356 if (!str.IsEmpty())
\r
365 void CMainFrame::OnFileSave()
\r
367 if (m_strPathName == _T(""))
\r
370 WriteFile(m_strPathName);
\r
373 void CMainFrame::OnFileSaveAs()
\r
375 // szFilters is a text string that includes two file name filters:
\r
376 // "*.my" for "MyType Files" and "*.*' for "All Files."
\r
377 CString Filters(_T("Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0"), 46);
\r
379 CString str = File.SaveFileDialog(0, OFN_OVERWRITEPROMPT, Filters, _T("txt"), this);
\r
381 if (!str.IsEmpty())
\r
390 void CMainFrame::SetFileName(LPCTSTR szFilePathName)
\r
392 //Truncate and save file name
\r
393 int i = lstrlen(szFilePathName)+1;
\r
394 while ((--i > 0) && (szFilePathName[i-1] != _T('\\')));
\r
396 m_strPathName = szFilePathName+i;
\r
399 void CMainFrame::SetWindowTitle()
\r
403 if (m_strPathName == _T("")) Title = _T("TextEdit - Untitled");
\r
405 else Title = _T("TextEdit - ") + m_strPathName;
\r
406 SetWindowText(Title);
\r
409 void CMainFrame::SetupToolBar()
\r
411 // Define the resource IDs for the toolbar
\r
412 AddToolBarButton( IDM_FILE_NEW );
\r
413 AddToolBarButton( IDM_FILE_OPEN );
\r
414 AddToolBarButton( IDM_FILE_SAVE );
\r
415 AddToolBarButton( 0 ); // Separator
\r
416 AddToolBarButton( IDM_EDIT_CUT );
\r
417 AddToolBarButton( IDM_EDIT_COPY );
\r
418 AddToolBarButton( IDM_EDIT_PASTE );
\r
419 AddToolBarButton( 0 ); // Separator
\r
420 AddToolBarButton( IDM_FILE_PRINT );
\r
421 AddToolBarButton( 0 ); // Separator
\r
422 AddToolBarButton( IDM_HELP_ABOUT );
\r
426 LRESULT CMainFrame::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
433 return WndProcDefault(uMsg, wParam, lParam);
\r
436 DWORD CALLBACK CMainFrame::MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
\r
438 // Required for StreamIn
\r
443 if (!::ReadFile((HANDLE)(DWORD_PTR) dwCookie, pbBuff, cb, (LPDWORD)pcb, NULL))
\r
444 ::MessageBox(NULL, _T("ReadFile Failed"), _T(""), MB_OK);
\r
449 DWORD CALLBACK CMainFrame::MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
\r
451 // Required for StreamOut
\r
456 if (!::WriteFile((HANDLE)(DWORD_PTR)dwCookie, pbBuff, cb, (LPDWORD)pcb, NULL))
\r
457 ::MessageBox(NULL, _T("WriteFile Failed"), _T(""), MB_OK);
\r