4 * Copyright 2000 Mike McCormack <Mike_McCormack@looksmart.com.au>
5 * Copyright 1997,98 Marcel Baur <mbaur@g26.ethz.ch>
6 * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * - Use wine Heap instead of malloc/free (done)
24 * - use scroll bars (vertical done)
25 * - cut 'n paste (clipboard)
29 * - encapsulate data structures (?) - half done
30 * - free unused memory
31 * - solve Open problems
32 * - smoother scrolling
33 * - separate view code and document code
35 * This program is intended as a testbed for winelib as much as
36 * a useful application.
47 extern BOOL
FileExists(LPCSTR szFilename
);
48 extern BOOL
DoCloseFile(void);
49 extern void DoOpenFile(LPCSTR szFileName
);
51 NOTEPAD_GLOBALS Globals
;
54 /* Using a pointer to pointer data structure to
55 achieve a little more efficiency. Hopefully
56 it will be worth it, because it complicates the
57 code - mjm 26 Jun 2000 */
59 #define BUFFERCHUNKSIZE 0xe0
60 typedef struct TAGLine
{
66 /* FIXME: make this info into a structure */
67 /* typedef struct tagBUFFER { */
72 DWORD dwXpos
=0,dwYpos
=0; /* position of caret in char coords */
73 DWORD dwCaretXpos
=0,dwCaretYpos
=0; /* position of caret in pixel coords */
74 TEXTMETRIC tm
; /* textmetric for current font */
75 RECT rectClient
; /* client rectangle of the window we're drawing in */
76 /* } BUFFER, *LPBUFFER */
78 VOID
InitFontInfo(HWND hWnd
)
80 HDC hDC
= GetDC(hWnd
);
84 GetTextMetrics(hDC
, &tm
);
98 /* convert x,y character co-ords into x pixel co-ord */
99 DWORD
CalcStringWidth(HDC hDC
, DWORD x
, DWORD y
)
111 if(lpBuffer
[y
].lpLine
== NULL
)
113 len
= (x
<lpBuffer
[y
].dwWidth
) ?
114 x
: lpBuffer
[y
].dwWidth
;
115 GetTextExtentPoint(hDC
, lpBuffer
[y
].lpLine
, len
, &size
);
120 void CalcCaretPos(HDC hDC
, DWORD dwXpos
, DWORD dwYpos
)
122 dwCaretXpos
= CalcStringWidth(hDC
, dwXpos
, dwYpos
);
123 dwCaretYpos
= tm
.tmHeight
*(dwYpos
-dwVOffset
);
124 SetCaretPos(dwCaretXpos
,dwCaretYpos
);
127 DWORD
GetLinesPerPage(HWND hWnd
)
129 return (rectClient
.bottom
/tm
.tmHeight
); /* round down */
132 /* render one line of text and blank space */
133 void RenderLine(HDC hDC
, DWORD lineno
)
141 /* erase the space at the end of a line using a white rectangle */
142 rect
.top
= tm
.tmHeight
*(lineno
-dwVOffset
);
143 rect
.bottom
= tm
.tmHeight
*(lineno
-dwVOffset
+1);
145 if(lpBuffer
&& (lineno
<dwLines
))
146 rect
.left
= CalcStringWidth(hDC
, lpBuffer
[lineno
].dwWidth
,lineno
);
149 rect
.right
= rectClient
.right
;
151 /* use the white pen so there's not outline */
152 hPrev
= SelectObject(hDC
, GetStockObject(WHITE_PEN
));
153 Rectangle(hDC
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
154 SelectObject(hDC
, hPrev
);
156 if(lpBuffer
&& lpBuffer
[lineno
].lpLine
)
158 TextOut(hDC
, 0, rect
.top
, lpBuffer
[lineno
].lpLine
,
159 lpBuffer
[lineno
].dwWidth
);
164 * Paint the buffer onto the window.
166 void RenderWindow(HDC hDC
) {
172 /* FIXME: render only necessary lines */
173 for(i
= dwVOffset
; i
< (dwVOffset
+GetLinesPerPage(0)); i
++)
180 * Check that correct buffers exist to access line y pos x
181 * Only manages memory.
183 * Returns TRUE if the line is accessable
184 * FALSE if there is a problem
186 BOOL
ValidateLine(DWORD y
,DWORD x
)
190 /* check to see that the BUFFER has enough lines */
192 if( (max
<=y
) || (lpBuffer
== NULL
))
195 max
+= BUFFERCHUNKSIZE
;
196 /* use GlobalAlloc first time round */
198 lpBuffer
= (LPLINE
) GlobalReAlloc((HGLOBAL
)lpBuffer
,GMEM_FIXED
,
201 lpBuffer
= (LPLINE
) GlobalAlloc(GMEM_FIXED
, max
*sizeof(LINE
));
204 ZeroMemory(&lpBuffer
[dwLines
], sizeof(LINE
)*(max
-dwLines
) );
208 /* check to see that the LINE is wide enough */
209 max
= lpBuffer
[y
].dwMaxWidth
;
210 if( (max
<= x
) || (lpBuffer
[y
].lpLine
== NULL
) )
213 max
+= BUFFERCHUNKSIZE
;
214 /* use GlobalAlloc first */
215 if(lpBuffer
[y
].lpLine
)
216 lpBuffer
[y
].lpLine
= (LPSTR
)GlobalReAlloc((HGLOBAL
)lpBuffer
[y
].lpLine
,
219 lpBuffer
[y
].lpLine
= (LPSTR
)GlobalAlloc( GMEM_FIXED
, max
);
220 if(lpBuffer
[y
].lpLine
== NULL
)
222 lpBuffer
[y
].dwWidth
= 0;
223 lpBuffer
[y
].dwMaxWidth
= max
;
228 /* inserts a new line into the buffer */
229 BOOL
DoNewLine(HDC hDC
)
234 /* check to see if we need more memory for the buffer pointers */
235 if(!ValidateLine(dwLines
,0))
238 /* shuffle up all the lines */
239 for(i
=dwLines
; i
>(dwYpos
+1); i
--)
241 lpBuffer
[i
] = lpBuffer
[i
-1];
244 ZeroMemory(&lpBuffer
[dwYpos
+1],sizeof(LINE
));
246 /* copy the characters after the carat (if any) to the next line */
247 src
= &lpBuffer
[dwYpos
].lpLine
[dwXpos
];
248 cnt
= lpBuffer
[dwYpos
].dwWidth
-dwXpos
;
249 if(!ValidateLine(dwYpos
+1,cnt
)) /* allocates the buffer */
250 return FALSE
; /* FIXME */
251 dst
= &lpBuffer
[dwYpos
+1].lpLine
[0];
252 memcpy(dst
, src
, cnt
);
253 lpBuffer
[dwYpos
+1].dwWidth
= cnt
;
254 lpBuffer
[dwYpos
].dwWidth
-= cnt
;
256 /* move the cursor */
261 /* update the window */
262 RenderLine(hDC
, dwYpos
-1);
263 RenderLine(hDC
, dwYpos
);
264 CalcCaretPos(hDC
, dwXpos
, dwYpos
);
265 /* FIXME: don't use globals */
266 SetScrollRange(Globals
.hMainWnd
, SB_VERT
, 0, dwLines
, TRUE
);
272 * Attempt a basic edit buffer
274 BOOL
AddCharToBuffer(HDC hDC
, char ch
)
276 /* we can use lpBuffer[dwYpos] */
277 if(!ValidateLine(dwYpos
,0))
280 /* shuffle the rest of the line*/
281 if(!ValidateLine(dwYpos
, lpBuffer
[dwYpos
].dwWidth
))
283 lpBuffer
[dwYpos
].dwWidth
++;
284 memmove(&lpBuffer
[dwYpos
].lpLine
[dwXpos
+1],
285 &lpBuffer
[dwYpos
].lpLine
[dwXpos
],
286 lpBuffer
[dwYpos
].dwWidth
-dwXpos
);
288 /* add the character */
289 lpBuffer
[dwYpos
].lpLine
[dwXpos
] = ch
;
294 /* update the window and cursor position */
295 RenderLine(hDC
,dwYpos
);
296 CalcCaretPos(hDC
,dwXpos
,dwYpos
);
302 /* erase a character */
303 BOOL
DoBackSpace(HDC hDC
)
309 if(lpBuffer
[dwYpos
].lpLine
&& (dwXpos
>0))
312 /* FIXME: use memmove */
313 for(i
=dwXpos
; i
<(lpBuffer
[dwYpos
].dwWidth
-1); i
++)
314 lpBuffer
[dwYpos
].lpLine
[i
]=lpBuffer
[dwYpos
].lpLine
[i
+1];
316 lpBuffer
[dwYpos
].dwWidth
--;
317 RenderLine(hDC
, dwYpos
);
318 CalcCaretPos(hDC
,dwXpos
,dwYpos
);
322 /* Erase a newline. To do this we join two lines */
329 oldlen
= lpBuffer
[dwYpos
-1].dwWidth
;
330 if(lpBuffer
[dwYpos
-1].lpLine
&&lpBuffer
[dwYpos
].lpLine
)
332 /* concatonate to the end of the line above line */
333 src
= &lpBuffer
[dwYpos
].lpLine
[0];
334 dest
= &lpBuffer
[dwYpos
-1].lpLine
[lpBuffer
[dwYpos
-1].dwWidth
];
335 len
= lpBuffer
[dwYpos
].dwWidth
;
337 /* check the length of the new line */
338 if(!ValidateLine(dwYpos
-1,lpBuffer
[dwYpos
-1].dwWidth
+ len
))
341 memcpy(dest
,src
,len
);
342 lpBuffer
[dwYpos
-1].dwWidth
+=len
;
343 GlobalFree( (HGLOBAL
)lpBuffer
[dwYpos
].lpLine
);
345 else if (!lpBuffer
[dwYpos
-1].lpLine
)
347 lpBuffer
[dwYpos
-1]=lpBuffer
[dwYpos
];
348 } /* else both are NULL */
349 RenderLine(hDC
,dwYpos
-1);
351 /* don't zero - it's going to get trashed anyhow */
353 /* shuffle up all the lines below this one */
354 for(i
=dwYpos
; i
<(dwLines
-1); i
++)
356 lpBuffer
[i
] = lpBuffer
[i
+1];
360 /* clear the last line */
361 ZeroMemory(&lpBuffer
[dwLines
-1],sizeof (LINE
));
362 RenderLine(hDC
,dwLines
-1);
365 /* adjust the cursor position to joining point */
369 CalcCaretPos(hDC
,dwXpos
,dwYpos
);
370 SetScrollRange(Globals
.hMainWnd
, SB_VERT
, 0, dwLines
, TRUE
);
375 /* as used by File->New */
376 void TrashBuffer(void)
380 /* variables belonging to the buffer */
383 for(i
=0; i
<dwLines
; i
++)
385 if(lpBuffer
[i
].lpLine
)
386 GlobalFree ((HGLOBAL
)lpBuffer
[i
].lpLine
);
387 ZeroMemory(&lpBuffer
[i
],sizeof (LINE
));
389 GlobalFree((HGLOBAL
)lpBuffer
);
395 /* variables belonging to the view */
399 /* FIXME: don't use globals */
400 SetScrollPos(Globals
.hMainWnd
, SB_VERT
, dwVOffset
, FALSE
);
401 SetScrollRange(Globals
.hMainWnd
, SB_VERT
, 0, dwLines
, TRUE
);
406 * Add a line to the buffer
408 /* FIXME: this breaks lines longer than BUFFERCHUNKSIZE */
410 LPSTR buffer
, /* pointer to buffer with file data */
411 DWORD size
, /* number of bytes available in buffer */
419 for(i
=0; i
<size
; i
++)
423 if(ValidateLine(dwLines
,i
))
425 memcpy(&lpBuffer
[dwLines
].lpLine
[0],&buffer
[0],i
);
426 lpBuffer
[dwLines
].dwWidth
= i
;
433 /* make a line of the rest */
434 if( (i
== BUFFERCHUNKSIZE
) || nomore
)
436 if(ValidateLine(dwLines
,i
))
438 memcpy(&lpBuffer
[dwLines
].lpLine
[0],&buffer
[0],i
);
439 lpBuffer
[dwLines
].dwWidth
= i
;
450 * This is probably overcomplicated by lpBuffer data structure...
451 * Read blocks from the file, then add each line from the
452 * block to the buffer until there is none left. If all
453 * a slab isn't used, try load some more data from the file.
455 void LoadBufferFromFile(LPCSTR szFileName
)
459 DWORD size
,i
,len
,bytes_left
,bytes_read
;
461 hFile
= CreateFile(szFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
462 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
463 if(hFile
== INVALID_HANDLE_VALUE
)
465 size
= BUFFERCHUNKSIZE
;
466 pTemp
= (LPSTR
) GlobalAlloc(GMEM_FIXED
, size
);
469 bytes_read
= 1; /* anything non-zero */
478 bytes_left
+=bytes_read
;
480 /* add strings to buffer */
483 (len
= CreateLine(&pTemp
[i
], bytes_left
, !bytes_read
));
484 i
+= len
,bytes_left
-=len
);
486 /* move leftover to front of buffer */
488 memmove(&pTemp
[0],&pTemp
[i
], bytes_left
);
493 BOOL
DoInput(HDC hDC
, WPARAM wParam
, LPARAM lParam
)
498 return DoBackSpace(hDC
);
500 return DoNewLine(hDC
);
502 return AddCharToBuffer(hDC
,wParam
);
506 BOOL
GotoHome(HWND hWnd
)
514 BOOL
GotoEndOfLine(HWND hWnd
)
516 dwXpos
= lpBuffer
[dwYpos
].dwWidth
;
520 BOOL
GotoDown(HWND hWnd
)
522 if((dwYpos
+1) >= dwLines
)
527 if (dwXpos
>lpBuffer
[dwYpos
].dwWidth
)
532 BOOL
GotoUp(HWND hWnd
)
537 if (dwXpos
>lpBuffer
[dwYpos
].dwWidth
)
542 BOOL
GotoLeft(HWND hWnd
)
550 return GotoEndOfLine(hWnd
);
554 BOOL
GotoRight(HWND hWnd
)
556 if(dwXpos
<lpBuffer
[dwYpos
].dwWidth
)
567 /* check the caret is still on the screen */
568 BOOL
ScrollABit(HWND hWnd
)
575 if(dwYpos
>(dwVOffset
+GetLinesPerPage(hWnd
)))
577 dwVOffset
= dwYpos
- GetLinesPerPage(hWnd
) + 1;
583 /* FIXME: move the window around so we can still see the caret */
584 VOID
DoEdit(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
592 case VK_HOME
: GotoHome(hWnd
);
595 case VK_END
: GotoEndOfLine(hWnd
);
598 case VK_LEFT
: GotoLeft(hWnd
);
601 case VK_RIGHT
: GotoRight(hWnd
);
604 case VK_DOWN
: GotoDown(hWnd
);
607 case VK_UP
: GotoUp(hWnd
);
617 CalcCaretPos(hDC
, dwXpos
, dwYpos
);
621 InvalidateRect(hWnd
, NULL
, FALSE
);
624 void ButtonDownToCaretPos(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
626 DWORD x
, y
, caretx
, carety
;
627 BOOL refine_guess
= TRUE
;
633 caretx
= x
/tm
.tmAveCharWidth
; /* guess */
634 carety
= dwVOffset
+ y
/tm
.tmHeight
;
642 refine_guess
= FALSE
;
645 /* if the cursor is past the bottom, put it after the last char */
646 if(refine_guess
&& (carety
>=dwLines
) )
649 caretx
=lpBuffer
[carety
].dwWidth
;
650 refine_guess
= FALSE
;
653 /* cursor past end of line? */
654 if(refine_guess
&& (x
>CalcStringWidth(hDC
,lpBuffer
[carety
].dwWidth
,carety
)))
656 caretx
= lpBuffer
[carety
].dwWidth
;
657 refine_guess
= FALSE
;
660 /* FIXME: doesn't round properly */
663 if(CalcStringWidth(hDC
,caretx
,carety
)<x
)
665 while( (caretx
<lpBuffer
[carety
].dwWidth
) &&
666 (CalcStringWidth(hDC
,caretx
+1,carety
)<x
))
671 while((caretx
>0)&&(CalcStringWidth(hDC
,caretx
-1,carety
)>x
))
676 /* set the caret's position */
679 CalcCaretPos(hDC
, caretx
, carety
);
683 void DoScroll(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
685 DWORD dy
= GetLinesPerPage(hWnd
);
687 switch(wParam
) /* vscroll code */
694 if(dwVOffset
<dwLines
)
698 if( (dy
+dwVOffset
) > dwLines
)
699 dwVOffset
= dwLines
- 1;
706 /* position scroll */
707 SetScrollPos(hWnd
, SB_VERT
, dwVOffset
, TRUE
);
710 /***********************************************************************
712 * NOTEPAD_MenuCommand
714 * All handling of main menu events
717 int NOTEPAD_MenuCommand (WPARAM wParam
)
720 case 0x100: DIALOG_FileNew(); break;
721 case 0x101: DIALOG_FileOpen(); break;
722 case 0x102: DIALOG_FileSave(); break;
723 case 0x103: DIALOG_FileSaveAs(); break;
724 case 0x104: DIALOG_FilePrint(); break;
725 case 0x105: DIALOG_FilePageSetup(); break;
726 case 0x106: DIALOG_FilePrinterSetup();break;
727 case 0x108: DIALOG_FileExit(); break;
729 case 0x110: DIALOG_EditUndo(); break;
730 case 0x111: DIALOG_EditCut(); break;
731 case 0x112: DIALOG_EditCopy(); break;
732 case 0x113: DIALOG_EditPaste(); break;
733 case 0x114: DIALOG_EditDelete(); break;
734 case 0x116: DIALOG_EditSelectAll(); break;
735 case 0x117: DIALOG_EditTimeDate();break;
736 case 0x119: DIALOG_EditWrap(); break;
738 case 0x120: DIALOG_Search(); break;
739 case 0x121: DIALOG_SearchNext(); break;
741 case 0x130: DIALOG_HelpContents(); break;
742 case 0x131: DIALOG_HelpSearch(); break;
743 case 0x132: DIALOG_HelpHelp(); break;
744 case 0x135: DIALOG_HelpLicense(); break;
745 case 0x136: DIALOG_HelpNoWarranty(); break;
746 case 0x137: DIALOG_HelpAboutWine(); break;
749 // LANGUAGE_DefaultHandle(wParam);
756 /***********************************************************************
761 LRESULT WINAPI
NOTEPAD_WndProc (HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
765 HANDLE hDrop
; /* drag & drop */
766 CHAR szFileName
[MAX_STRING_LEN
];
769 lstrcpy(szFileName
, "");
774 GetClientRect(hWnd
, &rectClient
);
779 CreateCaret(Globals
.hMainWnd
, 0, 1, tm
.tmHeight
);
780 SetCaretPos(dwCaretXpos
, dwCaretYpos
);
781 ShowCaret(Globals
.hMainWnd
);
789 GetClientRect(hWnd
, &rectClient
);
790 hContext
= BeginPaint(hWnd
, &ps
);
791 RenderWindow(hContext
);
796 DoEdit(hWnd
, wParam
, lParam
);
800 GetClientRect(hWnd
, &rectClient
);
802 hContext
= GetDC(hWnd
);
803 DoInput(hContext
,wParam
,lParam
);
804 ReleaseDC(hWnd
,hContext
);
809 /* figure out where the mouse was clicked */
810 ButtonDownToCaretPos(hWnd
, wParam
, lParam
);
814 DoScroll(hWnd
, wParam
, lParam
);
815 InvalidateRect(hWnd
, NULL
, FALSE
); /* force a redraw */
819 /* FIXME: this is a bit messy */
820 NOTEPAD_MenuCommand(wParam
);
821 InvalidateRect(hWnd
, NULL
, FALSE
); /* force a redraw */
822 hContext
= GetDC(hWnd
);
823 CalcCaretPos(hContext
,dwXpos
,dwYpos
);
824 ReleaseDC(hWnd
,hContext
);
827 case WM_DESTROYCLIPBOARD
:
828 MessageBox(Globals
.hMainWnd
, "Empty clipboard", "Debug", MB_ICONEXCLAMATION
);
842 GetClientRect(Globals
.hMainWnd
, &Windowsize
);
846 /* User has dropped a file into main window */
847 hDrop
= (HANDLE
) wParam
;
848 DragQueryFile(hDrop
, 0, (CHAR
*) &szFileName
, sizeof(szFileName
));
850 DoOpenFile(szFileName
);
854 return DefWindowProc (hWnd
, msg
, wParam
, lParam
);
859 int AlertFileDoesNotExist(LPSTR szFileName
) {
862 CHAR szMessage
[MAX_STRING_LEN
];
863 CHAR szRessource
[MAX_STRING_LEN
];
865 LoadString(Globals
.hInstance
, STRING_DOESNOTEXIST
, szRessource
,
866 sizeof(szRessource
));
867 wsprintf(szMessage
, szRessource
, szFileName
);
869 LoadString(Globals
.hInstance
, STRING_ERROR
, szRessource
, sizeof(szRessource
));
871 nResult
= MessageBox(Globals
.hMainWnd
, szMessage
, szRessource
,
872 MB_ICONEXCLAMATION
| MB_YESNO
);
877 void HandleCommandLine(LPSTR cmdline
)
880 while (*cmdline
&& (*cmdline
== ' ' || *cmdline
== '-'))
885 if (*cmdline
++ == ' ') continue;
888 if (option
) cmdline
++;
889 while (*cmdline
&& *cmdline
== ' ') cmdline
++;
894 case 'P': printf("Print file: ");
895 /* Not yet able to print a file */
902 /* file name is passed in the command line */
907 if (FileExists(cmdline
))
914 /* try to find file with ".txt" extention */
915 if (!strcmp(".txt", cmdline
+ strlen(cmdline
) - strlen(".txt")))
922 strncpy(buf
, cmdline
, MAX_PATH
- strlen(".txt") - 1);
925 file_exists
= FileExists(buf
);
931 DoOpenFile(file_name
);
932 InvalidateRect(Globals
.hMainWnd
, NULL
, FALSE
);
936 switch (AlertFileDoesNotExist(file_name
)) {
938 DoOpenFile(file_name
);
949 /***********************************************************************
954 int PASCAL
WinMain (HINSTANCE hInstance
, HINSTANCE prev
, LPSTR cmdline
, int show
)
958 char className
[] = "NPClass"; /* To make sure className >= 0x10000 */
959 char winName
[] = "Notepad";
966 Globals
.lpszIniFile
= "notepad.ini";
967 Globals
.lpszIcoFile
= "notepad.ico";
969 Globals
.hInstance
= hInstance
;
972 Globals
.hMainIcon
= ExtractIcon(Globals
.hInstance
,
973 Globals
.lpszIcoFile
, 0);
975 if (!Globals
.hMainIcon
) {
976 Globals
.hMainIcon
= LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON
));
979 lstrcpy(Globals
.szFindText
, "");
980 lstrcpy(Globals
.szFileName
, "");
981 lstrcpy(Globals
.szMarginTop
, "25 mm");
982 lstrcpy(Globals
.szMarginBottom
, "25 mm");
983 lstrcpy(Globals
.szMarginLeft
, "20 mm");
984 lstrcpy(Globals
.szMarginRight
, "20 mm");
985 lstrcpy(Globals
.szHeader
, "&n");
986 lstrcpy(Globals
.szFooter
, "Page &s");
987 lstrcpy(Globals
.Buffer
, "Hello World");
990 class.style
= CS_HREDRAW
| CS_VREDRAW
;
991 class.lpfnWndProc
= NOTEPAD_WndProc
;
992 class.cbClsExtra
= 0;
993 class.cbWndExtra
= 0;
994 class.hInstance
= Globals
.hInstance
;
995 class.hIcon
= LoadIcon (0, IDI_APPLICATION
);
996 class.hCursor
= LoadCursor (0, IDC_ARROW
);
997 class.hbrBackground
= GetStockObject (WHITE_BRUSH
);
998 class.lpszMenuName
= 0;
999 class.lpszClassName
= className
;
1002 if (!RegisterClass (&class)) return FALSE
;
1007 Globals
.hMainWnd
= CreateWindow (className
, winName
,
1008 WS_OVERLAPPEDWINDOW
+ WS_HSCROLL
+ WS_VSCROLL
,
1009 CW_USEDEFAULT
, 0, CW_USEDEFAULT
, 0, 0,
1010 LoadMenu(Globals
.hInstance
, STRING_MENU_Xx
),
1011 Globals
.hInstance
, 0);
1013 Globals
.hFindReplaceDlg
= 0;
1015 LANGUAGE_LoadMenus();
1017 SetMenu(Globals
.hMainWnd
, Globals
.hMainMenu
);
1019 ShowWindow (Globals
.hMainWnd
, show
);
1020 UpdateWindow (Globals
.hMainWnd
);
1022 /* Set up dialogs */
1024 /* Identify Messages originating from FindReplace */
1026 Globals
.nCommdlgFindReplaceMsg
= RegisterWindowMessage("commdlg_FindReplace");
1027 if (Globals
.nCommdlgFindReplaceMsg
==0) {
1028 MessageBox(Globals
.hMainWnd
, "Could not register commdlg_FindReplace window message",
1029 "Error", MB_ICONEXCLAMATION
);
1032 HandleCommandLine(cmdline
);
1034 /* Set up Drag&Drop */
1036 DragAcceptFiles(Globals
.hMainWnd
, TRUE
);
1038 /* now enter mesage loop */
1040 while (GetMessage (&msg
, 0, 0, 0)) {
1041 if (IsDialogMessage(Globals
.hFindReplaceDlg
, &msg
)!=0) {
1042 /* Message belongs to FindReplace dialog */
1043 /* We just let IsDialogMessage handle it */
1047 /* Message belongs to the Notepad Main Window */
1048 TranslateMessage (&msg
);
1049 DispatchMessage (&msg
);