'------------------------------------------------------------------------------- ' ' PBNOTE.BAS for 32-bit PB/DLL ' Copyright (c) 1997 by PowerBASIC, Inc. ' ' A simple text editor using MDI windows. If Windows 95 is detected, a ' RichEdit control is used for support of more than 64k. In Windows NT ' a standard Edit control is used since its faster. ' ' Note: Windows 95 thunks 'down' to the 16-bit GDI for edit boxes, so ' edit boxes are limited to 64k in Windows 95. Edit boxes in ' Windows NT are unlimited in size. ' '------------------------------------------------------------------------------- ' ** Eliminate unnecessary macros %NOANIMATE = 1 %NODRAGLIST = 1 %NOHEADER = 1 %NOIMAGELIST = 1 %NOLISTVIEW = 1 %NOTABCONTROL = 1 %NOTRACKBAR = 1 %NOTREEVIEW = 1 %NOUPDOWN = 1 '------------------------------------------------------------------------------ $COMPILE EXE $RESOURCE "PBNOTE.PBR" $INCLUDE "WIN32API.INC" $INCLUDE "COMMCTRL.INC" $INCLUDE "COMDLG32.INC" $INCLUDE "RICHEDIT.INC" $INCLUDE "MDI32.INC" '------------------------------------------------------------------------------ %ID_TOOLBAR = %WM_USER + 1024 %IDB_BUTTONS = %ID_TOOLBAR + 1 %IDC_EDIT = %IDB_BUTTONS + 1 '* FILE %IDM_NEW = %WM_USER + 2048& ' New File %IDM_OPEN = %IDM_NEW + 1& ' Open File %IDM_SAVE = %IDM_OPEN + 1& ' Save %IDM_SAVEAS = %IDM_SAVE + 1& ' Save As %IDM_EXIT = %IDM_SAVEAS + 1& ' Exit '* EDIT %IDM_UNDO = %IDM_EXIT + 1& ' Undo %IDM_CLEAR = %IDM_UNDO + 1& ' Clear %IDM_CUT = %IDM_CLEAR + 1& ' Cut %IDM_COPY = %IDM_CUT + 1& ' Copy %IDM_PASTE = %IDM_COPY + 1& ' Paste '* WINDOW %IDM_TILE = %IDM_PASTE + 1& ' Tile windows %IDM_CASCADE = %IDM_TILE + 1& ' Cascade windows %IDM_ARRANGE = %IDM_CASCADE + 1& ' Arrange icons %IDM_CLOSE = %IDM_ARRANGE + 1& ' Close all '* HELP %IDM_ABOUT = %IDM_CLOSE + 1& ' About box '------------------------------------------------------------------------------ GLOBAL hInst AS LONG GLOBAL hStatus AS LONG GLOBAL hToolbar AS LONG GLOBAL hWndMain AS LONG GLOBAL hWndClient AS LONG GLOBAL hFont AS LONG GLOBAL w95 AS LONG '------------------------------------------------------------------------------ DECLARE FUNCTION FileNam(BYVAL Src AS STRING) AS STRING DECLARE FUNCTION FilePath(BYVAL Src AS STRING) AS STRING DECLARE FUNCTION GetEdit() AS LONG DECLARE SUB CenterWindow(BYVAL hWnd AS LONG) DECLARE SUB SaveFile(BYVAL Ask AS LONG) '------------------------------------------------------------------------------ FUNCTION WinMain (BYVAL hInstance AS LONG, _ BYVAL hPrevInstance AS LONG, _ lpCmdLine AS ASCIIZ PTR, _ BYVAL iCmdShow AS LONG) AS LONG LOCAL Msg AS tagMsg LOCAL wndclass AS WndClassEx LOCAL szClassName AS ASCIIZ * 80 LOCAL hWnd AS LONG LOCAL hMenu AS LONG LOCAL hAccel AS LONG LOCAL hRichEd AS LONG LOCAL vi AS OSVERSIONINFO hInst = hInstance ' ** Detect version of Windows vi.dwOsVersionInfoSize = SIZEOF(vi) GetVersionEx vi w95 = (vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS) ' ** Register Main Window Class szClassName = "PBNOTE" wndclass.cbSize = SIZEOF(WndClass) wndclass.style = %CS_HREDRAW OR %CS_VREDRAW wndclass.lpfnWndProc = CODEPTR( WndProc ) wndclass.cbClsExtra = 0 wndclass.cbWndExtra = 0 wndclass.hInstance = hInstance wndclass.hIcon = LoadIcon( hInstance, "PROGRAM" ) wndclass.hCursor = LoadCursor( %NULL, BYVAL %IDC_ARROW ) wndclass.hbrBackground = %COLOR_APPWORKSPACE + 1 wndclass.lpszMenuName = %NULL wndclass.lpszClassName = VARPTR( szClassName ) wndclass.hIconSm = LoadIcon( hInstance, BYVAL %IDI_APPLICATION ) IF ISFALSE(RegisterClassEx(wndclass)) THEN RegisterClass BYVAL (VARPTR(wndclass) + 4) END IF ' ** Register Code Window Class szClassName = "PBNOTE32" wndclass.cbSize = SIZEOF(WndClass) wndclass.style = %CS_HREDRAW OR %CS_VREDRAW OR %CS_DBLCLKS wndclass.lpfnWndProc = CODEPTR( CodeProc ) wndclass.cbClsExtra = 0 wndclass.cbWndExtra = 4 wndclass.hInstance = hInst wndclass.hIcon = LoadIcon( hInstance, "NOTE" ) wndclass.hCursor = LoadCursor( %NULL, BYVAL %IDC_IBEAM ) wndclass.hbrBackground = %COLOR_WINDOW + 1 wndclass.lpszMenuName = %NULL wndclass.lpszClassName = VARPTR( szClassName ) wndclass.hIconSm = LoadIcon( hInstance, BYVAL %IDI_APPLICATION ) IF ISFALSE(RegisterClassEx(wndclass)) THEN RegisterClass BYVAL (VARPTR(wndclass) + 4) END IF hMenu = LoadMenu(hInstance, "MAINMENU") ' Create a window using the registered class hWndMain = CreateWindow("PBNOTE", _ ' window class name "PBNOTE", _ ' window caption %WS_OVERLAPPEDWINDOW, _ ' window style %CW_USEDEFAULT, _ ' initial x position %CW_USEDEFAULT, _ ' initial y position %CW_USEDEFAULT, _ ' initial x size %CW_USEDEFAULT, _ ' initial y size %NULL, _ ' parent window handle hMenu, _ ' window menu handle hInstance, _ ' program instance handle BYVAL %NULL) ' creation parameters hFont = GetStockObject(%OEM_FIXED_FONT) hAccel = LoadAccelerators(hInstance, "PBNOTE") ' ** Use a RichEdit control if in Windows 95 IF w95 THEN hRichEd = LoadLibrary("RICHED32.DLL") END IF ShowWindow hWndMain, iCmdShow UpdateWindow hWndMain ' ** Message handler loop WHILE ISTRUE(GetMessage(Msg, BYVAL %NULL, 0, 0)) IF ISFALSE(TranslateMDISysAccel(hWndClient, Msg)) THEN IF ISFALSE(TranslateAccelerator(hWndMain, hAccel, Msg)) THEN TranslateMessage Msg DispatchMessage Msg END IF END IF WEND FUNCTION = msg.wParam END FUNCTION ' WinMain '------------------------------------------------------------------------------ FUNCTION WndProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, _ BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG LOCAL dwProc AS DWORD LOCAL tbab AS TBADDBITMAP LOCAL lpToolTip AS TOOLTIPTEXT PTR LOCAL cc AS CLIENTCREATESTRUCT LOCAL hMdi AS LONG LOCAL Style AS LONG LOCAL f AS STRING LOCAL Buffer AS STRING LOCAL Path AS STRING LOCAL RetVal AS LONG LOCAL hFile AS LONG STATIC tRect AS RECT STATIC zText AS ASCIIZ * 255 STATIC ToolHeight AS LONG STATIC StatHeight AS LONG STATIC hEdit AS LONG SELECT CASE wMsg CASE %WM_CREATE DIM tbb(0 to 6) AS STATIC TBBUTTON ' Initialize the common controls InitCommonControls ' Fill the TBBUTTON array with button information tbb(0).iBitmap = %STD_FILENEW tbb(0).idCommand = %IDM_NEW tbb(0).fsState = %TBSTATE_ENABLED tbb(0).fsStyle = %TBSTYLE_BUTTON tbb(0).dwData = 0 tbb(0).iString = 0 tbb(1).iBitmap = %STD_FILEOPEN tbb(1).idCommand = %IDM_OPEN tbb(1).fsState = %TBSTATE_ENABLED tbb(1).fsStyle = %TBSTYLE_BUTTON tbb(1).dwData = 0 tbb(1).iString = 0 tbb(2).iBitmap = %STD_FILESAVE tbb(2).idCommand = %IDM_SAVE tbb(2).fsState = %TBSTATE_ENABLED tbb(2).fsStyle = %TBSTYLE_BUTTON tbb(2).dwData = 0 tbb(2).iString = 0 tbb(3).iBitmap = 0 tbb(3).idCommand = 0 tbb(3).fsState = %TBSTATE_ENABLED tbb(3).fsStyle = %TBSTYLE_SEP tbb(3).dwData = 0 tbb(3).iString = 0 tbb(4).iBitmap = %STD_CUT tbb(4).idCommand = %IDM_CUT tbb(4).fsState = %TBSTATE_ENABLED tbb(4).fsStyle = %TBSTYLE_BUTTON tbb(4).dwData = 0 tbb(4).iString = 0 tbb(5).iBitmap = %STD_COPY tbb(5).idCommand = %IDM_COPY tbb(5).fsState = %TBSTATE_ENABLED tbb(5).fsStyle = %TBSTYLE_BUTTON tbb(5).dwData = 0 tbb(5).iString = 0 tbb(6).iBitmap = %STD_PASTE tbb(6).idCommand = %IDM_PASTE tbb(6).fsState = %TBSTATE_ENABLED tbb(6).fsStyle = %TBSTYLE_BUTTON tbb(6).dwData = 0 tbb(6).iString = 0 ' Create the status bar window hStatus = CreateStatusWindow(%WS_CHILD OR %WS_BORDER OR %WS_VISIBLE OR %SBS_SIZEGRIP, _ "", hWnd, 200) ' Create the toolbar window hToolbar = CreateToolbarEx(hWnd, %WS_CHILD OR %TBSTYLE_TOOLTIPS, _ %ID_TOOLBAR, 12, %HINST_COMMCTRL, %IDB_STD_LARGE_COLOR, _ tbb(0), 7, 0, 0, 100, 30, LEN(TBBUTTON)) ' Create MDI Client window cc.idFirstChild = 0 hWndClient = CreateWindowEx(%WS_EX_CLIENTEDGE, "MDICLIENT", BYVAL %NULL, _ %WS_CHILD OR %WS_CLIPCHILDREN OR %WS_VISIBLE OR %WS_VSCROLL OR %WS_HSCROLL, _ 0, 0, 0, 0, hWnd, &H0CAC, hInst, cc) ' Display the toolbar SendMessage hToolbar, %TB_AUTOSIZE, 0, 0 ShowWindow hToolbar, %SW_SHOW 'Get the size of the toolbar and status bar GetWindowRect hToolbar, tRect ToolHeight = tRect.nBottom - tRect.nTop GetWindowRect hStatus, tRect StatHeight = tRect.nBottom - tRect.nTop EXIT FUNCTION CASE %WM_SIZE IF wParam <> %SIZE_MINIMIZED THEN SendMessage hStatus, wMsg, wParam, lParam SendMessage hToolbar, wMsg, wParam, lParam GetClientRect hWnd, tRect MoveWindow hWndClient, _ tRect.nLeft, _ ToolHeight, _ tRect.nRight, _ tRect.nBottom - (ToolHeight + StatHeight), _ %TRUE END IF EXIT FUNCTION CASE %WM_NOTIFY lpToolTip = lParam IF @lpToolTip.hdr.code = %TTN_NEEDTEXT THEN LoadString hInst, @lpToolTip.hdr.idFrom, zText, SIZEOF(zText) @lpToolTip.lpszText = VARPTR(zText) END IF EXIT FUNCTION CASE %WM_MENUSELECT LoadString hInst, wParam, zText, SIZEOF(zText) SendMessage hStatus, %WM_SETTEXT, 0, VARPTR(zText) CASE %WM_COMMAND SELECT CASE LOWRD(wParam) CASE %IDM_NEW hMdi = CreateMdiChild("PBNOTE32", hWndClient, "", 0) ShowWindow hMdi, %SW_SHOW EXIT FUNCTION CASE %IDM_OPEN Path = CURDIR$ f = "*.TXT" Style = %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY OR %OFN_LONGNAMES IF OpenFileDialog(hWndMain, "Open File", f, Path, _ "Text Files|*.TXT|All Files|*.*", "TXT", Style) THEN hMdi = CreateMdiChild("PBNOTE32", hWndClient, f, 0) ShowWindow hMdi, %SW_SHOW END IF CASE %IDM_SAVE SaveFile %FALSE CASE %IDM_SAVEAS SaveFile %TRUE CASE %IDM_EXIT SendMessage hWnd, %WM_DESTROY, wParam, lParam CASE %IDM_ABOUT dwProc = CODEPTR(AboutProc) DialogBox hInst, "ABOUT", hWnd, dwProc CASE %IDM_CLOSE WHILE MdiGetActive(hWndClient) IF SendMessage(MdiGetActive(hWndClient), %WM_CLOSE, 0, 0) THEN EXIT DO END IF WEND CASE %IDM_CUT : SendMessage GetEdit, %WM_CUT, 0, 0 CASE %IDM_COPY : SendMessage GetEdit, %WM_COPY, 0, 0 CASE %IDM_PASTE : SendMessage GetEdit, %EM_PASTESPECIAL, %CF_TEXT, 0 CASE %IDM_UNDO : SendMessage GetEdit, %EM_UNDO, 0, 0 CASE %IDM_CLEAR : SendMessage GetEdit, %WM_CLEAR, 0, 0 CASE %IDM_TILE : MdiTile hWndClient, %WM_MDITILE CASE %IDM_CASCADE : MdiCascade hWndClient CASE %IDM_ARRANGE : MdiIconArrange hWndClient END SELECT CASE %WM_PAINT CASE %WM_DESTROY PostQuitMessage 0 FUNCTION = 0 EXIT FUNCTION END SELECT FUNCTION = DefFrameProc(hWnd, hWndClient, wMsg, wParam, lParam) END FUNCTION '------------------------------------------------------------------------------ FUNCTION CodeProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, _ BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG LOCAL hEdit AS LONG LOCAL hFile AS LONG LOCAL Buffer AS STRING LOCAL RetVal AS LONG STATIC rc AS RECT STATIC zText AS ASCIIZ * 255 SELECT CASE wMsg CASE %WM_CREATE GetClientRect hWnd, rc IF w95 THEN hEdit = CreateWindowEx(%WS_EX_CLIENTEDGE, "RichEdit", BYVAL %NULL, %WS_CHILD OR %WS_VISIBLE OR _ %ES_MULTILINE OR %WS_VSCROLL OR %WS_HSCROLL OR _ %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR %ES_NOHIDESEL, _ 0, 0, 0, 0, hWnd, %IDC_EDIT, hInst, BYVAL %NULL) ELSE hEdit = CreateWindowEx(%WS_EX_CLIENTEDGE, "Edit", BYVAL %NULL, %WS_CHILD OR %WS_VISIBLE OR _ %ES_MULTILINE OR %WS_VSCROLL OR %WS_HSCROLL OR _ %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR %ES_NOHIDESEL, _ 0, 0, 0, 0, hWnd, %IDC_EDIT, hInst, BYVAL %NULL) END IF SendMessage hEdit, %WM_SETFONT, hFont, 0 SendMessage hEdit, %EM_SETLIMITTEXT, &H100000&, 0 GetWindowText hWnd, zText, SIZEOF(zText) IF LEN(zText) THEN hFile = FREEFILE OPEN zText FOR BINARY AS hFile GET$ hFile, LOF(hFile), Buffer CLOSE hFile SetWindowText hEdit, BYVAL STRPTR(Buffer) ELSE SetWindowText hWnd, "Untitled" END IF CASE %WM_SIZE MoveWindow GetDlgItem(hWnd, %IDC_EDIT), 0, 0, LOWRD(lParam), HIWRD(lParam), %TRUE CASE %WM_SETFOCUS SetFocus GetEdit CASE %WM_PAINT CASE %WM_CLOSE IF SendMessage(GetEdit, %EM_GETMODIFY, 0, 0) THEN GetWindowText hWnd, zText, SIZEOF(zText) RetVal = MsgBox("Save current changes? " + FileNam(zText), _ %MB_YESNOCANCEL OR %MB_ICONEXCLAMATION, _ "PBNOTE") IF RetVal = %IDCANCEL THEN EXIT FUNCTION ELSEIF RetVal = %IDYES THEN SaveFile %FALSE END IF END IF CASE %WM_DESTROY END SELECT FUNCTION = DefMDIChildProc(hWnd, wMsg, wParam, lParam) END FUNCTION '------------------------------------------------------------------------------ FUNCTION AboutProc(BYVAL hDlg AS LONG, BYVAL wMsg AS LONG, _ BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG SELECT CASE wMsg CASE %WM_INITDIALOG CenterWindow hDlg EnableWindow hWndMain, %FALSE FUNCTION = 1 CASE %WM_COMMAND SELECT CASE LOWRD(wParam) CASE %IDCANCEL EndDialog hDlg, 0 EnableWindow hWndMain, %TRUE FUNCTION = 1 CASE %IDOK, 103 EndDialog hDlg, 1 EnableWindow hWndMain, %TRUE FUNCTION = 1 END SELECT END SELECT END FUNCTION '------------------------------------------------------------------------------ SUB SaveFile(BYVAL Ask AS LONG) LOCAL Path AS STRING LOCAL f AS STRING LOCAL Style AS LONG LOCAL hFile AS LONG LOCAL Buffer AS STRING LOCAL zText AS ASCIIZ * 255 GetWindowText MdiGetActive(hWndClient), zText, SIZEOF(zText) IF zText = "Untitled" THEN Path = CURDIR$ f = "" Ask = %TRUE ELSE Path = FilePath(zText) f = FileNam(zText) END IF Style = %OFN_HIDEREADONLY OR %OFN_LONGNAMES IF ISTRUE(Ask) THEN IF ISFALSE(SaveFileDialog(hWndMain, "Save File", f, Path, _ "Text Files|*.TXT|All Files|*.*", "TXT", Style)) THEN EXIT SUB END IF END IF hFile = FREEFILE OPEN f FOR BINARY AS hFile Buffer = SPACE$(GetWindowTextLength(GetEdit) + 1) GetWindowText GetEdit, BYVAL STRPTR(Buffer), LEN(Buffer) PUT$ hFile, LEFT$(Buffer, LEN(Buffer)-1) CLOSE hFile SetWindowText MdiGetActive(hWndClient), BYVAL STRPTR(f) END SUB '------------------------------------------------------------------------------ FUNCTION GetEdit() AS LONG FUNCTION = GetDlgItem(MdiGetActive(hWndClient), %IDC_EDIT) END FUNCTION '------------------------------------------------------------------------------ FUNCTION FileNam(BYVAL Src AS STRING) AS STRING LOCAL x AS LONG FOR x = LEN(Src) TO 1 STEP -1 IF (ASC(Src, x) = 92) OR (ASC(Src, x) = 58) THEN EXIT FOR END IF NEXT x FUNCTION = MID$(Src, x + 1) END FUNCTION '------------------------------------------------------------------------------ FUNCTION FilePath(BYVAL Src AS STRING) AS STRING LOCAL x AS LONG FOR x = LEN(Src) TO 1 STEP -1 IF (ASC(Src, x) = 92) OR (ASC(Src, x) = 58) THEN EXIT FOR END IF NEXT x FUNCTION = LEFT$(Src, x) END FUNCTION '------------------------------------------------------------------------------ SUB CenterWindow(BYVAL hWnd AS LONG) DIM WndRect AS RECT DIM x AS LONG DIM y AS LONG GetWindowRect hWnd, WndRect x = (GetSystemMetrics(%SM_CXSCREEN)-(WndRect.nRight-WndRect.nLeft))\2 y = (GetSystemMetrics(%SM_CYSCREEN)-(WndRect.nBottom-WndRect.nTop+GetSystemMetrics(%SM_CYCAPTION)))\2 SetWindowPos hWnd, %NULL, x, y, 0, 0, %SWP_NOSIZE OR %SWP_NOZORDER END SUB