POPPAD with a Menu and Accelerators

In Chapter 6 we created a program called POPPAD1 that uses a child window edit control to mimic some of the workings of Windows' Note Pad program. In this chapter we'll add a File and Edit menu and call it POPPAD2. The Edit items will all be functional; we'll finish the File functions in Chapter 10 and the Print function in Chapter 15. POPPAD2 is shown in Figure 9-12 beginning on the following page.

POPPAD2.MAK

#-----------------------

# POPPAD2.MAK make file

#-----------------------

poppad2.exe : poppad2.obj poppad2.def poppad2.res

link poppad2, /align:16, NUL, /nod slibcew libw, poppad2.def

rc poppad2.res

poppad2.obj : poppad2.c poppad2.h

cl -c -Gsw -Ow -W2 -Zp poppad2.c

poppad2.res : poppad2.rc poppad2.h poppad2.ico

rc -r poppad2.rc

POPPAD2.C

/*-----------------------------------------------------

POPPAD2.C -- Popup Editor Version 2 (includes menu)

(c) Charles Petzold, 1990

-----------------------------------------------------*/

#include <windows.h>

#include "poppad2.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

char szAppName [] = "PopPad2" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpszCmdLine, int nCmdShow)

{

HANDLE hAccel ;

HWND hwnd ;

MSG msg ;

WNDCLASS wndclass ;

if (!hPrevInstance)

{

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (hInstance, szAppName) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = szAppName ;

wndclass.lpszClassName = szAppName ;

RegisterClass (&wndclass) ;

}

hwnd = CreateWindow (szAppName, szAppName,

WS_OVERLAPPEDWINDOW,

GetSystemMetrics (SM_CXSCREEN) / 4,

GetSystemMetrics (SM_CYSCREEN) / 4,

GetSystemMetrics (SM_CXSCREEN) / 2,

GetSystemMetrics (SM_CYSCREEN) / 2,

NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, nCmdShow) ;

UpdateWindow (hwnd) ;

hAccel = LoadAccelerators (hInstance, szAppName) ;

while (GetMessage (&msg, NULL, 0, 0))

{

if (!TranslateAccelerator (hwnd, hAccel, &msg))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

}

return msg.wParam ;

}

AskConfirmation (HWND hwnd)

{

return MessageBox (hwnd, "Really want to close PopPad2?",

szAppName, MB_YESNO | MB_ICONQUESTION) ;

}

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)

{

static HWND hwndEdit ;

LONG lSelect ;

WORD wEnable ;

switch (message)

{

case WM_CREATE :

hwndEdit = CreateWindow ("edit", NULL,

WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |

WS_BORDER | ES_LEFT | ES_MULTILINE |

ES_AUTOHSCROLL | ES_AUTOVSCROLL,

0, 0, 0, 0,

hwnd, 1, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;

return 0 ;

case WM_SETFOCUS :

SetFocus (hwndEdit) ;

return 0 ;

case WM_SIZE :

MoveWindow (hwndEdit, 0, 0, LOWORD (lParam),

HIWORD (lParam), TRUE) ;

return 0 ;

case WM_INITMENUPOPUP :

if (lParam == 1)

{

EnableMenuItem (wParam, IDM_UNDO,

SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?

MF_ENABLED : MF_GRAYED) ;

EnableMenuItem (wParam, IDM_PASTE,

IsClipboardFormatAvailable (CF_TEXT) ?

MF_ENABLED : MF_GRAYED) ;

lSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0L) ;

if (HIWORD (lSelect) == LOWORD (lSelect))

wEnable = MF_GRAYED ;

else

wEnable = MF_ENABLED ;

EnableMenuItem (wParam, IDM_CUT, wEnable) ;

EnableMenuItem (wParam, IDM_COPY, wEnable) ;

EnableMenuItem (wParam, IDM_CLEAR, wEnable) ;

return 0 ;

}

break ;

case WM_COMMAND :

if (LOWORD (lParam))

{

if (wParam == 1 && HIWORD (lParam) == EN_ERRSPACE)

MessageBox (hwnd, "Edit control out of space.",

szAppName, MB_OK | MB_ICONSTOP) ;

return 0 ;

}

else switch (wParam)

{

case IDM_NEW :

case IDM_OPEN :

case IDM_SAVE :

case IDM_SAVEAS :

case IDM_PRINT :

MessageBeep (0) ;

return 0 ;

case IDM_EXIT :

SendMessage (hwnd, WM_CLOSE, 0, 0L) ;

return 0 ;

case IDM_ABOUT :

MessageBox (hwnd,

"POPPAD2 (c) Charles Petzold, 1990",

szAppName, MB_OK | MB_ICONINFORMATION) ;

return 0 ;

case IDM_UNDO :

SendMessage (hwndEdit, WM_UNDO, 0, 0L) ;

return 0 ;

case IDM_CUT :

SendMessage (hwndEdit, WM_CUT, 0, 0L) ;

return 0 ;

case IDM_COPY :

SendMessage (hwndEdit, WM_COPY, 0, 0L) ;

return 0 ;

case IDM_PASTE :

SendMessage (hwndEdit, WM_PASTE, 0, 0L) ;

return 0 ;

case IDM_CLEAR :

SendMessage (hwndEdit, WM_CLEAR, 0, 0L) ;

return 0 ;

case IDM_SELALL :

SendMessage (hwndEdit, EM_SETSEL, 0,

MAKELONG (0, 32767)) ;

return 0 ;

}

break ;

case WM_CLOSE :

if (IDYES == AskConfirmation (hwnd))

DestroyWindow (hwnd) ;

return 0 ;

case WM_QUERYENDSESSION :

if (IDYES == AskConfirmation (hwnd))

return 1L ;

else

return 0 ;

case WM_DESTROY :

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}

POPPAD2.RC

/*----------------------------

POPPAD2.RC resource script

----------------------------*/

#include <windows.h>

#include "poppad2.h"

PopPad2 ICON poppad2.ico

PopPad2 MENU

{

POPUP "&File"

{

MENUITEM "&New", IDM_NEW

MENUITEM "&Open...", IDM_OPEN

MENUITEM "&Save", IDM_SAVE

MENUITEM "Save &As...", IDM_SAVEAS

MENUITEM SEPARATOR

MENUITEM "&Print", IDM_PRINT

MENUITEM SEPARATOR

MENUITEM "E&xit", IDM_EXIT

MENUITEM "&About PopPad2...", IDM_ABOUT

}

POPUP "&Edit"

{

MENUITEM "&Undo\tAlt+BkSp", IDM_UNDO

MENUITEM SEPARATOR

MENUITEM "Cu&t\tShift+Del", IDM_CUT

MENUITEM "&Copy\tCtrl+Ins", IDM_COPY

MENUITEM "&Paste\tShift+Ins", IDM_PASTE

MENUITEM "C&lear\tDel", IDM_CLEAR

MENUITEM SEPARATOR

MENUITEM "&Select All", IDM_SELALL

}

}

PopPad2 ACCELERATORS

{

VK_DELETE, IDM_CUT, VIRTKEY, SHIFT

VK_INSERT, IDM_COPY, VIRTKEY, CONTROL

VK_INSERT, IDM_PASTE, VIRTKEY, SHIFT

VK_DELETE, IDM_CLEAR, VIRTKEY

}

POPPAD2.H

/*-----------------------

POPPAD2.H header file

-----------------------*/

#define IDM_NEW 1

#define IDM_OPEN 2

#define IDM_SAVE 3

#define IDM_SAVEAS 4

#define IDM_PRINT 5

#define IDM_EXIT 6

#define IDM_ABOUT 7

#define IDM_UNDO 8

#define IDM_CUT 9

#define IDM_COPY 10

#define IDM_PASTE 11

#define IDM_CLEAR 12

#define IDM_SELALL 13

POPPAD2.ICO

POPPAD2.DEF

;------------------------------------

; POPPAD2.DEF module definition file

;------------------------------------

NAME POPPAD2

DESCRIPTION 'Popup Editor Version 2 (c) Charles Petzold, 1990'

EXETYPE WINDOWS

STUB 'WINSTUB.EXE'

CODE PRELOAD MOVEABLE DISCARDABLE

DATA PRELOAD MOVEABLE MULTIPLE

HEAPSIZE 1024

STACKSIZE 8192

EXPORTS WndProc

The POPPAD2.RC resource script file contains the menu and accelerator table. You'll notice that the accelerators are all indicated within the text strings of the Edit popup menu following the tab (\t) character.