/* A sample program from the book
"Programming Windows 95" by Charles Petzold and Paul Yao. */
/*---------------------------------------
POPPAD.C -- Popup Editor
(c) Charles Petzold, 1996
---------------------------------------*/
#include <windows.h>
#include <commdlg.h>
#include <stdlib.h>
#include "poppad.h"
#define EDITID 1
#define UNTITLED "(untitled)"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
// Functions in POPFILE.C
void PopFileInitialize (HWND) ;
BOOL PopFileOpenDlg (HWND, PSTR, PSTR) ;
BOOL PopFileSaveDlg (HWND, PSTR, PSTR) ;
BOOL PopFileRead (HWND, PSTR) ;
BOOL PopFileWrite (HWND, PSTR) ;
// Functions in POPFIND.C
HWND PopFindFindDlg (HWND) ;
HWND PopFindReplaceDlg (HWND) ;
BOOL PopFindFindText (HWND, int *, LPFINDREPLACE) ;
BOOL PopFindReplaceText (HWND, int *, LPFINDREPLACE) ;
BOOL PopFindNextText (HWND, int *) ;
BOOL PopFindValidFind (void) ;
// Functions in POPFONT.C
void PopFontInitialize (HWND) ;
BOOL PopFontChooseFont (HWND) ;
void PopFontSetFont (HWND) ;
void PopFontDeinitialize (void) ;
// Functions in POPPRNT.C
BOOL PopPrntPrintFile (HINSTANCE, HWND, HWND, PSTR) ;
// Global variables
static char szAppName[] = "PopPad" ;
static HWND hDlgModeless ;
HMENU hMenu,hMenuPopup;
HGLOBAL hgbl1,hgbl2;
int iReturn;
struct
{
BYTE fVirt;
WORD key;
WORD cmd;
}
accel[] =
{
FCONTROL, 'N', IDM_NEW,
FCONTROL, 'O', IDM_OPEN,
FCONTROL, 'S', IDM_SAVE,
FCONTROL, 'P', IDM_PRINT,
FCONTROL, 'Z', IDM_UNDO,
FALT | FVIRTKEY, VK_BACK, IDM_UNDO,
FCONTROL, 'X', IDM_CUT,
FSHIFT | FVIRTKEY, VK_DELETE, IDM_CUT,
FCONTROL, 'C', IDM_COPY,
FCONTROL | FVIRTKEY, VK_INSERT, IDM_COPY,
FCONTROL, 'V', IDM_PASTE,
FSHIFT | FVIRTKEY, VK_INSERT, IDM_PASTE,
FVIRTKEY, VK_DELETE, IDM_CLEAR,
FCONTROL, 'F', IDM_FIND,
FVIRTKEY, VK_F3, IDM_NEXT,
FCONTROL, 'R', IDM_REPLACE,
FVIRTKEY, VK_F1, IDM_HELP
} ;
LPWORD lpwAlign ( LPWORD lpIn)
{
ULONG ul;
ul = (ULONG) lpIn;
ul +=3;
ul >>=2;
ul <<=2;
return (LPWORD) ul;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MSG msg ;
HWND hwnd ;
HACCEL hAccel ;
WNDCLASSEX wndclass ;
LPACCEL lpaccl = accel ;
LPDLGTEMPLATE lpdt;
LPDLGITEMTEMPLATE lpdit;
LPWORD lpw;
LPWSTR lpwsz;
hgbl1 = GlobalAlloc(GMEM_ZEROINIT, 1024);
if (!hgbl1)
return -1;
lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl1);
// Define a dialog box.
lpdt->style = WS_POPUP | WS_DLGFRAME;
lpdt->cdit = 4; // number of controls
lpdt->x = 20; lpdt->y = 20;
lpdt->cx = 160; lpdt->cy = 80;
lpw = (LPWORD) (lpdt + 1);
*lpw++ = 0; // no menu
*lpw++ = 0; // predefined dialog box class (by default)
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"About Box");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->x = 0; lpdit->y = 12;
lpdit->cx = 160; lpdit->cy = 8;
lpdit->id = -1; // text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // static class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"PopPad");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->x = 0; lpdit->y = 36;
lpdit->cx = 160; lpdit->cy = 8;
lpdit->id = -1; // text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // static class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"Popup Editor for Microsoft Windows");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->x = 0; lpdit->y = 48;
lpdit->cx = 160; lpdit->cy = 8;
lpdit->id = -1; // text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // static class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"Copyright (c) Charles Petzold , 1996");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
//-----------------------
// Define an OK button.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
lpdit->x = 64; lpdit->y = 60;
lpdit->cx = 32; lpdit->cy = 14;
lpdit->id = IDOK; // OK button identifier
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0080; // button class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"OK");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
GlobalUnlock(hgbl1);
hgbl2 = GlobalAlloc(GMEM_ZEROINIT, 1024);
if (!hgbl2)
return -1;
lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl2);
// Define a dialog box.
lpdt->style = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE ;
lpdt->cdit = 4; // number of controls
lpdt->x = 20; lpdt->y = 20;
lpdt->cx = 100; lpdt->cy = 76;
lpw = (LPWORD) (lpdt + 1);
*lpw++ = 0; // no menu
*lpw++ = 0; // predefined dialog box class (by default)
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"PopPad");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->x = 0; lpdit->y = 10;
lpdit->cx = 100; lpdit->cy = 8;
lpdit->id = -1; // text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // static class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"Sending");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->x = 0; lpdit->y = 20;
lpdit->cx = 100; lpdit->cy = 8;
lpdit->id = IDD_FNAME; // text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // static class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
//-----------------------
// Define a static text control.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->x = 0; lpdit->y = 30;
lpdit->cx = 100; lpdit->cy = 8;
lpdit->id = -1; // text identifier
lpdit->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0082; // static class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"to print spooler.");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
//-----------------------
// Define an OK button.
//-----------------------
lpw = lpwAlign (lpw);
lpdit = (LPDLGITEMTEMPLATE) lpw;
lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
lpdit->x = 34; lpdit->y = 50;
lpdit->cx = 32; lpdit->cy = 14;
lpdit->id = IDCANCEL; // OK button identifier
lpw = (LPWORD) (lpdit + 1);
*lpw++ = 0xFFFF;
*lpw++ = 0x0080; // button class
lpwsz = (LPWSTR) lpw;
lstrcpyW(lpwsz, L"Cancel");
lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);
*lpw++ = 0; // no creation data
GlobalUnlock(hgbl2);
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
// wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
wndclass.hIcon = LoadImage (NULL, "poppad.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;
// wndclass.hIconSm = LoadIcon (hInstance, szAppName) ;
wndclass.hIconSm = LoadImage (NULL, "poppad.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE) ;
RegisterClassEx (&wndclass) ;
hMenu = CreateMenu ();
hMenuPopup = CreateMenu ();
AppendMenu (hMenuPopup, MF_STRING, IDM_NEW, "&New\tCtrl+N");
AppendMenu (hMenuPopup, MF_STRING, IDM_OPEN, "&Open...\tCtrl+O");
AppendMenu (hMenuPopup, MF_STRING, IDM_SAVE, "&Save\tCtrl+S");
AppendMenu (hMenuPopup, MF_STRING, IDM_SAVEAS, "Save &As...");
AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL);
AppendMenu (hMenuPopup, MF_STRING, IDM_PRINT, "&Print...\tCtrl+P");
AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL);
AppendMenu (hMenuPopup, MF_STRING, IDM_EXIT, "E&xit");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenuPopup, "&File");
hMenuPopup = CreateMenu ();
AppendMenu (hMenuPopup, MF_STRING, IDM_UNDO, "&Undo\tCtrl+Z");
AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL);
AppendMenu (hMenuPopup, MF_STRING, IDM_CUT, "Cu&t\tCtrl+X");
AppendMenu (hMenuPopup, MF_STRING, IDM_COPY, "&Copy\tCtrl+C");
AppendMenu (hMenuPopup, MF_STRING, IDM_PASTE, "&Paste\tCtrl+V");
AppendMenu (hMenuPopup, MF_STRING, IDM_CLEAR, "De&lete\tDel");
AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL);
AppendMenu (hMenuPopup, MF_STRING, IDM_SELALL, "&Select All");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenuPopup, "&Edit");
hMenuPopup = CreateMenu ();
AppendMenu (hMenuPopup, MF_STRING, IDM_FIND, "&Find...\tCtrl+F");
AppendMenu (hMenuPopup, MF_STRING, IDM_NEXT, "Find &Next\tF3");
AppendMenu (hMenuPopup, MF_STRING, IDM_REPLACE, "R&eplace...\tCtrl+R");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenuPopup, "&Search");
hMenuPopup = CreateMenu ();
AppendMenu (hMenuPopup, MF_STRING, IDM_FONT, "&Font...");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenuPopup, "F&ormat");
hMenuPopup = CreateMenu ();
AppendMenu (hMenuPopup, MF_STRING, IDM_HELP, "&Help");
AppendMenu (hMenuPopup, MF_STRING, IDM_ABOUT, "&About PopPad...");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenuPopup, "&Help");
hwnd = CreateWindow (szAppName, NULL,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, hMenu, hInstance, szCmdLine) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
//hAccel = LoadAccelerators (hInstance, szAppName) ;
hAccel = CreateAcceleratorTable(lpaccl, 17);
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == NULL || !IsDialogMessage (hDlgModeless, &msg))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
}
GlobalFree(hgbl1);
GlobalFree(hgbl2);
return msg.wParam ;
}
void DoCaption (HWND hwnd, char *szTitleName)
{
char szCaption[64 + _MAX_FNAME + _MAX_EXT] ;
sprintf (szCaption, "%s - %s", szAppName,
szTitleName[0] ? szTitleName : UNTITLED) ;
SetWindowText (hwnd, szCaption) ;
}
void OkMessage (HWND hwnd, char *szMessage, char *szTitleName)
{
char szBuffer[64 + _MAX_FNAME + _MAX_EXT] ;
sprintf (szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED) ;
MessageBox (hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION) ;
}
short AskAboutSave (HWND hwnd, char *szTitleName)
{
char szBuffer[64 + _MAX_FNAME + _MAX_EXT] ;
sprintf (szBuffer, "Save current changes in %s?",
szTitleName[0] ? szTitleName : UNTITLED) ;
iReturn = MessageBox (hwnd, szBuffer, szAppName,
MB_YESNOCANCEL | MB_ICONQUESTION) ;
if (iReturn == IDYES)
if (!SendMessage (hwnd, WM_COMMAND, IDM_SAVE, 0L))
iReturn = IDCANCEL ;
return iReturn ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static BOOL bNeedSave = FALSE ;
static char szFileName[_MAX_PATH] ;
static char szTitleName[_MAX_FNAME + _MAX_EXT] ;
static HINSTANCE hInst ;
static HWND hwndEdit ;
static int iOffset ;
static UINT iMsgFindReplace ;
int iSelBeg, iSelEnd, iEnable ;
LPFINDREPLACE pfr ;
switch (iMsg)
{
case WM_CREATE :
hInst = ((LPCREATESTRUCT) lParam) -> hInstance ;
// Create the edit control child window
hwndEdit = CreateWindow ("edit", NULL,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
WS_BORDER | ES_LEFT | ES_MULTILINE |
ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0, 0, 0, 0,
hwnd, (HMENU) EDITID, hInst, NULL) ;
SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ;
// Initialize common dialog box stuff
PopFileInitialize (hwnd) ;
PopFontInitialize (hwndEdit) ;
iMsgFindReplace = RegisterWindowMessage (FINDMSGSTRING) ;
// Process command line
lstrcpy (szFileName, (PSTR)
(((LPCREATESTRUCT) lParam)->lpCreateParams)) ;
if (strlen (szFileName) > 0)
{
GetFileTitle (szFileName, szTitleName,
sizeof (szTitleName)) ;
if (!PopFileRead (hwndEdit, szFileName))
OkMessage (hwnd, "File %s cannot be read!",
szTitleName) ;
}
DoCaption (hwnd, szTitleName) ;
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 :
switch (lParam)
{
case 1 : // Edit menu
// Enable Undo if edit control can do it
EnableMenuItem ((HMENU) wParam, IDM_UNDO,
SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?
MF_ENABLED : MF_GRAYED) ;
// Enable Paste if text is in the clipboard
EnableMenuItem ((HMENU) wParam, IDM_PASTE,
IsClipboardFormatAvailable (CF_TEXT) ?
MF_ENABLED : MF_GRAYED) ;
// Enable Cut, Copy, and Del if text is selected
SendMessage (hwndEdit, EM_GETSEL, (WPARAM) &iSelBeg,
(LPARAM) &iSelEnd) ;
iEnable = iSelBeg != iSelEnd ? MF_ENABLED : MF_GRAYED ;
EnableMenuItem ((HMENU) wParam, IDM_CUT, iEnable) ;
EnableMenuItem ((HMENU) wParam, IDM_COPY, iEnable) ;
EnableMenuItem ((HMENU) wParam, IDM_CLEAR, iEnable) ;
break ;
case 2 : // Search menu
// Enable Find, Next, and Replace if modeless
// dialogs are not already active
iEnable = hDlgModeless == NULL ?
MF_ENABLED : MF_GRAYED ;
EnableMenuItem ((HMENU) wParam, IDM_FIND, iEnable) ;
EnableMenuItem ((HMENU) wParam, IDM_NEXT, iEnable) ;
EnableMenuItem ((HMENU) wParam, IDM_REPLACE, iEnable) ;
break ;
}
return 0 ;
case WM_COMMAND :
// Messages from edit control
if (lParam && LOWORD (wParam) == EDITID)
{
switch (HIWORD (wParam))
{
case EN_UPDATE :
bNeedSave = TRUE ;
return 0 ;
case EN_ERRSPACE :
case EN_MAXTEXT :
MessageBox (hwnd, "Edit control out of space.",
szAppName, MB_OK | MB_ICONSTOP) ;
return 0 ;
}
break ;
}
switch (LOWORD (wParam))
{
// Messages from File menu
case IDM_NEW :
if (bNeedSave && IDCANCEL ==
AskAboutSave (hwnd, szTitleName))
return 0 ;
SetWindowText (hwndEdit, "\0") ;
szFileName[0] = '\0' ;
szTitleName[0] = '\0' ;
DoCaption (hwnd, szTitleName) ;
bNeedSave = FALSE ;
return 0 ;
case IDM_OPEN :
if (bNeedSave && IDCANCEL ==
AskAboutSave (hwnd, szTitleName))
return 0 ;
if (PopFileOpenDlg (hwnd, szFileName, szTitleName)!=0)
{
if (!PopFileRead (hwndEdit, szFileName))
{
OkMessage (hwnd, "Could not read file %s!",
szTitleName) ;
szFileName[0] = '\0' ;
szTitleName[0] = '\0' ;
}
}
DoCaption (hwnd, szTitleName) ;
bNeedSave = FALSE ;
return 0 ;
case IDM_SAVE :
if (szFileName[0])
{
if (PopFileWrite (hwndEdit, szFileName))
{
bNeedSave = FALSE ;
return 1 ;
}
else
OkMessage (hwnd, "Could not write file %s",
szTitleName) ;
return 0 ;
}
// fall through
case IDM_SAVEAS :
if (PopFileSaveDlg (hwnd, szFileName, szTitleName))
{
DoCaption (hwnd, szTitleName) ;
if (PopFileWrite (hwndEdit, szFileName))
{
bNeedSave = FALSE ;
return 1 ;
}
else
OkMessage (hwnd, "Could not write file %s",
szTitleName) ;
}
return 0 ;
case IDM_PRINT :
if (!PopPrntPrintFile (hInst, hwnd, hwndEdit,
szTitleName))
OkMessage (hwnd, "Could not print file %s",
szTitleName) ;
return 0 ;
case IDM_EXIT :
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
return 0 ;
// Messages from Edit menu
case IDM_UNDO :
SendMessage (hwndEdit, WM_UNDO, 0, 0) ;
return 0 ;
case IDM_CUT :
SendMessage (hwndEdit, WM_CUT, 0, 0) ;
return 0 ;
case IDM_COPY :
SendMessage (hwndEdit, WM_COPY, 0, 0) ;
return 0 ;
case IDM_PASTE :
SendMessage (hwndEdit, WM_PASTE, 0, 0) ;
return 0 ;
case IDM_CLEAR :
SendMessage (hwndEdit, WM_CLEAR, 0, 0) ;
return 0 ;
case IDM_SELALL :
SendMessage (hwndEdit, EM_SETSEL, 0, -1) ;
return 0 ;
// Messages from Search menu
case IDM_FIND :
SendMessage (hwndEdit, EM_GETSEL, NULL,
(LPARAM) &iOffset) ;
hDlgModeless = PopFindFindDlg (hwnd) ;
return 0 ;
case IDM_NEXT :
SendMessage (hwndEdit, EM_GETSEL, NULL,
(LPARAM) &iOffset) ;
if (PopFindValidFind ())
PopFindNextText (hwndEdit, &iOffset) ;
else
hDlgModeless = PopFindFindDlg (hwnd) ;
return 0 ;
case IDM_REPLACE :
SendMessage (hwndEdit, EM_GETSEL, NULL,
(LPARAM) &iOffset) ;
hDlgModeless = PopFindReplaceDlg (hwnd) ;
return 0 ;
case IDM_FONT :
if (PopFontChooseFont (hwnd))
PopFontSetFont (hwndEdit) ;
return 0 ;
// Messages from Help menu
case IDM_HELP :
OkMessage (hwnd, "Help not yet implemented!", "\0") ;
return 0 ;
case IDM_ABOUT :
DialogBoxIndirect(hInst, (LPDLGTEMPLATE) hgbl1,
hwnd, (DLGPROC) AboutDlgProc);
return 0 ;
}
break ;
case WM_CLOSE :
if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
DestroyWindow (hwnd) ;
return 0 ;
case WM_QUERYENDSESSION :
if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
return 1 ;
return 0 ;
case WM_DESTROY :
PopFontDeinitialize () ;
PostQuitMessage (0) ;
return 0 ;
default:
// Process "Find-Replace" iMsgs
if (iMsg == iMsgFindReplace)
{
pfr = (LPFINDREPLACE) lParam ;
if (pfr->Flags & FR_DIALOGTERM)
hDlgModeless = NULL ;
if (pfr->Flags & FR_FINDNEXT)
if (!PopFindFindText (hwndEdit, &iOffset, pfr))
OkMessage (hwnd, "Text not found!", "\0") ;
if (pfr->Flags & FR_REPLACE ||
pfr->Flags & FR_REPLACEALL)
if (!PopFindReplaceText (hwndEdit, &iOffset, pfr))
OkMessage (hwnd, "Text not found!", "\0") ;
if (pfr->Flags & FR_REPLACEALL)
while (PopFindReplaceText (hwndEdit, &iOffset, pfr)) ;
return 0 ;
}
break ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_INITDIALOG :
return TRUE ;
case WM_COMMAND :
switch (LOWORD (wParam))
{
case IDOK :
EndDialog (hDlg, 0) ;
return TRUE ;
}
break ;
}
return FALSE ;
}
#pragma importf "popfile.c"
#pragma importf "popfind.c"
#pragma importf "popfont.c"
#pragma importf "popprnt.c"
/*------------------------------------------
POPFILE.C -- Popup Editor File Functions
------------------------------------------*/
#include <windows.h>
#include <commdlg.h>
#include <stdlib.h>
#include <stdio.h>
static OPENFILENAME ofn ;
void PopFileInitialize (HWND hwnd)
{
//static char szFilter[] = "Text Files (*.TXT)\0*.txt\0" \
// "ASCII Files (*.ASC)\0*.asc\0" \
// "All Files (*.*)\0*.*\0\0" ;
static char szFilter[256], chReplace;
UINT i,cbString;
strcpy(szFilter,
"Text Files (*.TXT)|*.txt|"
"ASCII Files (*.ASC)|*.asc|"
"All files (*.*)|*.*||");
cbString = strlen(szFilter);
chReplace = szFilter[cbString-1];
for (i=0; szFilter[i]; i++)
if (szFilter[i] == chReplace) szFilter[i] = '\0';
ofn.lStructSize = sizeof (OPENFILENAME) ;
ofn.hwndOwner = hwnd ;
ofn.hInstance = NULL ;
ofn.lpstrFilter = szFilter ;
ofn.lpstrCustomFilter = NULL ;
ofn.nMaxCustFilter = 0 ;
ofn.nFilterIndex = 0 ;
ofn.lpstrFile = NULL ; // Set in Open and Close functions
ofn.nMaxFile = _MAX_PATH ;
ofn.lpstrFileTitle = NULL ; // Set in Open and Close functions
ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ;
ofn.lpstrInitialDir = NULL ;
ofn.lpstrTitle = NULL ;
ofn.Flags = 0 ; // Set in Open and Close functions
ofn.nFileOffset = 0 ;
ofn.nFileExtension = 0 ;
ofn.lpstrDefExt = "txt" ;
ofn.lCustData = 0L ;
ofn.lpfnHook = NULL ;
ofn.lpTemplateName = NULL ;
}
BOOL PopFileOpenDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName)
{
ofn.hwndOwner = hwnd ;
ofn.lpstrFile = pstrFileName ;
ofn.lpstrFileTitle = pstrTitleName ;
ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT ;
return GetOpenFileName (&ofn) ;
}
BOOL PopFileSaveDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName)
{
ofn.hwndOwner = hwnd ;
ofn.lpstrFile = pstrFileName ;
ofn.lpstrFileTitle = pstrTitleName ;
ofn.Flags = OFN_OVERWRITEPROMPT ;
return GetSaveFileName (&ofn) ;
}
static long PopFileLength (FILE *file)
{
int iCurrentPos, iFileLength ;
iCurrentPos = ftell (file) ;
fseek (file, 0, SEEK_END) ;
iFileLength = ftell (file) ;
fseek (file, iCurrentPos, SEEK_SET) ;
return iFileLength ;
}
BOOL PopFileRead (HWND hwndEdit, PSTR pstrFileName)
{
FILE *file ;
int iLength ;
PSTR pstrBuffer ;
//printf("pstrFileName = %s\n", pstrFileName);
if (NULL == (file = fopen (pstrFileName, "rb")))
return FALSE ;
iLength = PopFileLength (file) ;
if (NULL == (pstrBuffer = (PSTR) malloc (iLength)))
{
fclose (file) ;
return FALSE ;
}
fread (pstrBuffer, 1, iLength, file) ;
fclose (file) ;
pstrBuffer[iLength] = '\0' ;
SetWindowText (hwndEdit, pstrBuffer) ;
free (pstrBuffer) ;
return TRUE ;
}
BOOL PopFileWrite (HWND hwndEdit, PSTR pstrFileName)
{
FILE *file ;
int iLength ;
PSTR pstrBuffer ;
if (NULL == (file = fopen (pstrFileName, "wb")))
return FALSE ;
iLength = GetWindowTextLength (hwndEdit) ;
if (NULL == (pstrBuffer = (PSTR) malloc (iLength + 1)))
{
fclose (file) ;
return FALSE ;
}
GetWindowText (hwndEdit, pstrBuffer, iLength + 1) ;
if (iLength != (int) fwrite (pstrBuffer, 1, iLength, file))
{
fclose (file) ;
free (pstrBuffer) ;
return FALSE ;
}
fclose (file) ;
free (pstrBuffer) ;
return TRUE ;
}
/*--------------------------------------------------------
POPFIND.C -- Popup Editor Search and Replace Functions
--------------------------------------------------------*/
#include <windows.h>
#include <commdlg.h>
#include <string.h>
#define MAX_STRING_LEN 256
static char szFindText [MAX_STRING_LEN] ;
static char szReplText [MAX_STRING_LEN] ;
HWND PopFindFindDlg (HWND hwnd)
{
static FINDREPLACE fr ; // must be static for modeless dialog!!!
fr.lStructSize = sizeof (FINDREPLACE) ;
fr.hwndOwner = hwnd ;
fr.hInstance = NULL ;
fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ;
fr.lpstrFindWhat = szFindText ;
fr.lpstrReplaceWith = NULL ;
fr.wFindWhatLen = sizeof (szFindText) ;
fr.wReplaceWithLen = 0 ;
fr.lCustData = 0 ;
fr.lpfnHook = NULL ;
fr.lpTemplateName = NULL ;
return FindText (&fr) ;
}
HWND PopFindReplaceDlg (HWND hwnd)
{
static FINDREPLACE fr ; // must be static for modeless dialog!!!
fr.lStructSize = sizeof (FINDREPLACE) ;
fr.hwndOwner = hwnd ;
fr.hInstance = NULL ;
fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ;
fr.lpstrFindWhat = szFindText ;
fr.lpstrReplaceWith = szReplText ;
fr.wFindWhatLen = sizeof (szFindText) ;
fr.wReplaceWithLen = sizeof (szReplText) ;
fr.lCustData = 0 ;
fr.lpfnHook = NULL ;
fr.lpTemplateName = NULL ;
return ReplaceText (&fr) ;
}
BOOL PopFindFindText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE pfr)
{
int iLength, iPos ;
PSTR pstrDoc, pstrPos ;
// Read in the edit document
iLength = GetWindowTextLength (hwndEdit) ;
if (NULL == (pstrDoc = (PSTR) malloc (iLength + 1)))
return FALSE ;
GetWindowText (hwndEdit, pstrDoc, iLength + 1) ;
// Search the document for the find string
pstrPos = strstr (pstrDoc + *piSearchOffset, pfr->lpstrFindWhat) ;
// Return an error code if the string cannot be found
if (pstrPos == NULL)
{
free (pstrDoc) ;
return FALSE ;
}
// Find the position in the document and the new start offset
iPos = pstrPos - pstrDoc ;
*piSearchOffset = iPos + strlen (pfr->lpstrFindWhat) ;
// Select the found text
SendMessage (hwndEdit, EM_SETSEL, iPos, *piSearchOffset) ;
SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0) ;
free (pstrDoc) ;
return TRUE ;
}
BOOL PopFindNextText (HWND hwndEdit, int *piSearchOffset)
{
FINDREPLACE fr ;
fr.lpstrFindWhat = szFindText ;
return PopFindFindText (hwndEdit, piSearchOffset, &fr) ;
}
BOOL PopFindReplaceText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE pfr)
{
// Find the text
if (!PopFindFindText (hwndEdit, piSearchOffset, pfr))
return FALSE ;
// Replace it
SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) pfr->lpstrReplaceWith) ;
return TRUE ;
}
BOOL PopFindValidFind (void)
{
return *szFindText != '\0' ;
}
/*------------------------------------------
POPFONT.C -- Popup Editor Font Functions
------------------------------------------*/
#include <windows.h>
#include <commdlg.h>
static LOGFONT logfont ;
static HFONT hFont ;
BOOL PopFontChooseFont (HWND hwnd)
{
CHOOSEFONT cf ;
cf.lStructSize = sizeof (CHOOSEFONT) ;
cf.hwndOwner = hwnd ;
cf.hDC = NULL ;
cf.lpLogFont = &logfont ;
cf.iPointSize = 0 ;
cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS
| CF_EFFECTS ;
cf.rgbColors = 0L ;
cf.lCustData = 0L ;
cf.lpfnHook = NULL ;
cf.lpTemplateName = NULL ;
cf.hInstance = NULL ;
cf.lpszStyle = NULL ;
cf.nFontType = 0 ; // Returned from ChooseFont
cf.nSizeMin = 0 ;
cf.nSizeMax = 0 ;
return ChooseFont (&cf) ;
}
void PopFontInitialize (HWND hwndEdit)
{
GetObject (GetStockObject (SYSTEM_FONT), sizeof (LOGFONT),
(PSTR) &logfont) ;
hFont = CreateFontIndirect (&logfont) ;
SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFont, 0) ;
}
void PopFontSetFont (HWND hwndEdit)
{
HFONT hFontNew ;
RECT rect ;
hFontNew = CreateFontIndirect (&logfont) ;
SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFontNew, 0) ;
DeleteObject (hFont) ;
hFont = hFontNew ;
GetClientRect (hwndEdit, &rect) ;
InvalidateRect (hwndEdit, &rect, TRUE) ;
}
void PopFontDeinitialize (void)
{
DeleteObject (hFont) ;
}
/*----------------------------------------------
POPPRNT.C -- Popup Editor Printing Functions
----------------------------------------------*/
#include <windows.h>
#include <commdlg.h>
#include <string.h>
#include <stdio.h>
#include "poppad.h"
BOOL bUserAbort ;
HWND hDlgPrint ;
BOOL CALLBACK PrintDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG :
EnableMenuItem (GetSystemMenu (hDlg, FALSE), SC_CLOSE,
MF_GRAYED) ;
return TRUE ;
case WM_COMMAND :
bUserAbort = TRUE ;
EnableWindow (GetParent (hDlg), TRUE) ;
DestroyWindow (hDlg) ;
hDlgPrint = 0 ;
return TRUE ;
}
return FALSE ;
}
BOOL CALLBACK AbortProc (HDC hPrinterDC, int iCode)
{
MSG msg ;
while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return !bUserAbort ;
}
BOOL PopPrntPrintFile (HINSTANCE hInst, HWND hwnd, HWND hwndEdit,
LPSTR szTitleName)
{
static DOCINFO di = { sizeof (DOCINFO), "", NULL } ;
static PRINTDLG pd ;
BOOL bSuccess ;
LPCTSTR pstrBuffer ;
int yChar, iCharsPerLine, iLinesPerPage, iTotalLines,
iTotalPages, iPage, iLine, iLineNum ;
TEXTMETRIC tm ;
WORD iColCopy, iNoiColCopy ;
pd.lStructSize = sizeof (PRINTDLG) ;
pd.hwndOwner = hwnd ;
pd.hDevMode = NULL ;
pd.hDevNames = NULL ;
pd.hDC = NULL ;
pd.Flags = PD_ALLPAGES | PD_COLLATE | PD_RETURNDC ;
pd.nFromPage = 0 ;
pd.nToPage = 0 ;
pd.nMinPage = 0 ;
pd.nMaxPage = 0 ;
pd.nCopies = 1 ;
pd.hInstance = NULL ;
pd.lCustData = 0L ;
pd.lpfnPrintHook = NULL ;
pd.lpfnSetupHook = NULL ;
pd.lpPrintTemplateName = NULL ;
pd.lpSetupTemplateName = NULL ;
pd.hPrintTemplate = NULL ;
pd.hSetupTemplate = NULL ;
if (!PrintDlg (&pd))
return TRUE ;
iTotalLines = (short) SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L) ;
if (iTotalLines == 0)
return TRUE ;
GetTextMetrics (pd.hDC, &tm) ;
yChar = tm.tmHeight + tm.tmExternalLeading ;
iCharsPerLine = GetDeviceCaps (pd.hDC, HORZRES) / tm.tmAveCharWidth ;
iLinesPerPage = GetDeviceCaps (pd.hDC, VERTRES) / yChar ;
iTotalPages = (iTotalLines + iLinesPerPage - 1) / iLinesPerPage ;
pstrBuffer = (LPCTSTR) HeapAlloc (GetProcessHeap (),
HEAP_NO_SERIALIZE, iCharsPerLine + 1) ;
EnableWindow (hwnd, FALSE) ;
bSuccess = TRUE ;
bUserAbort = FALSE ;
//hDlgPrint = CreateDialog (hInst, (LPCTSTR) "PrintDlgBox", hwnd, PrintDlgProc) ;
hDlgPrint = CreateDialogIndirect(hInst,
(LPDLGTEMPLATE) hgbl2,
hwnd,
(DLGPROC) PrintDlgProc);
SetDlgItemText (hDlgPrint, IDD_FNAME, szTitleName) ;
SetAbortProc (pd.hDC, AbortProc) ;
GetWindowText (hwnd, (PTSTR) di.lpszDocName, sizeof (PTSTR)) ;
if (StartDoc (pd.hDC, &di) > 0)
{
for (iColCopy = 0 ;
iColCopy < ((WORD) pd.Flags & PD_COLLATE ? pd.nCopies : 1) ;
iColCopy++)
{
for (iPage = 0 ; iPage < iTotalPages ; iPage++)
{
for (iNoiColCopy = 0 ;
iNoiColCopy < (pd.Flags & PD_COLLATE ? 1 : pd.nCopies) ;
iNoiColCopy++)
{
if (StartPage (pd.hDC) < 0)
{
bSuccess = FALSE ;
break ;
}
for (iLine = 0 ; iLine < iLinesPerPage ; iLine++)
{
iLineNum = iLinesPerPage * iPage + iLine ;
if (iLineNum > iTotalLines)
break ;
*(int *) pstrBuffer = iCharsPerLine ;
TextOut (pd.hDC, 0, yChar * iLine, pstrBuffer,
(int) SendMessage (hwndEdit, EM_GETLINE,
(WPARAM) iLineNum, (LPARAM) pstrBuffer)) ;
}
if (EndPage (pd.hDC) < 0)
{
bSuccess = FALSE ;
break ;
}
if (bUserAbort)
break ;
}
if (!bSuccess || bUserAbort)
break ;
}
if (!bSuccess || bUserAbort)
break ;
}
}
else
bSuccess = FALSE ;
if (bSuccess)
EndDoc (pd.hDC) ;
if (!bUserAbort)
{
EnableWindow (hwnd, TRUE) ;
DestroyWindow (hDlgPrint) ;
}
HeapFree (GetProcessHeap (), 0, (LPVOID) pstrBuffer) ;
DeleteDC (pd.hDC) ;
return bSuccess && !bUserAbort ;
}