Using the code below to demonstrate my problem, does not demonstrate my problem (surprise).
But using the same code (%WM_SIZE) section in my wicked huge program (hence "Code Not SHOWN") causes a "Invalid Memory Address GPF"
So I started looking at what was different, and what is different is my Main program is a MDI Dialog of sorts, so I grabbed "PbNote2" and tried the same test.
So am I looking at something I did? or an MDI vs SDI problem? or a (shudder) "Bug"??? Or any idea what I should be looking into???
My only clues at the time are DDT vs SDK, or MDI vs SDI, or SOMETHING I am overlooking?????
My only clue is the offending line is " DIALOG PIXELS HwndMain, HwndMainRect.nLeft, HwndMainRect.nBottom TO UNITS HwndMainRect.nLeft, HwndMainRect.nBottom
"
and it does not matter if I change the "HwndMainRect.nLeft, HwndMainRect.nBottom" to xx, yy so I am at a loss????
Code:
#PBFORMS CREATED V1.51 '------------------------------------------------------------------------------ ' The first line in this file is a PB/Forms metastatement. ' It should ALWAYS be the first line of the file. Other ' PB/Forms metastatements are placed at the beginning and ' end of "Named Blocks" of code that should be edited ' with PBForms only. Do not manually edit or delete these ' metastatements or PB/Forms will not be able to reread ' the file correctly. See the PB/Forms documentation for ' more information. ' Named blocks begin like this: #PBFORMS BEGIN ... ' Named blocks end like this: #PBFORMS END ... ' Other PB/Forms metastatements such as: ' #PBFORMS DECLARATIONS ' are used by PB/Forms to insert additional code. ' Feel free to make changes anywhere else in the file. '------------------------------------------------------------------------------ #COMPILE EXE #DIM ALL '------------------------------------------------------------------------------ ' ** Includes ** '------------------------------------------------------------------------------ #PBFORMS BEGIN INCLUDES #IF NOT %DEF(%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #PBFORMS END INCLUDES '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Constants ** '------------------------------------------------------------------------------ #PBFORMS BEGIN CONSTANTS %IDD_DIALOG1 = 101 #PBFORMS END CONSTANTS '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Declarations ** '------------------------------------------------------------------------------ DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG #PBFORMS DECLARATIONS GLOBAL HwndMain AS LONG '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Main Application Entry Point ** '------------------------------------------------------------------------------ FUNCTION PBMAIN() ShowDIALOG1 %HWND_DESKTOP END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** CallBacks ** '------------------------------------------------------------------------------ CALLBACK FUNCTION ShowDIALOG1Proc() SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG ' Initialization handler CASE %WM_NCACTIVATE STATIC hWndSaveFocus AS DWORD IF ISFALSE CBWPARAM THEN ' Save control focus hWndSaveFocus = GetFocus() ELSEIF hWndSaveFocus THEN ' Restore control focus SetFocus(hWndSaveFocus) hWndSaveFocus = 0 END IF CASE %WM_SIZE LOCAL HwndMainRect AS RECT LOCAL x AS LONG LOCAL y AS LONG LOCAL xx AS LONG LOCAL yy AS LONG '*** Get Toolbar and statusbar height GetWindowRect HwndMain, HwndMainRect MSGBOX STR$(HwndMainRect.nLeft) + "," + STR$(HwndMainRect.nBottom) DIALOG PIXELS HwndMain, HwndMainRect.nLeft, HwndMainRect.nBottom TO UNITS HwndMainRect.nLeft, HwndMainRect.nBottom MSGBOX STR$(HwndMainRect.nLeft) + "," + STR$(HwndMainRect.nBottom) 'MSGBOX STR$(xx) + "," + STR$(yy) CASE %WM_COMMAND ' Process control notifications SELECT CASE AS LONG CBCTL END SELECT END SELECT END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Dialogs ** '------------------------------------------------------------------------------ FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG1->-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "Dialog1", 70, 70, 201, 121, %WS_POPUP OR %WS_BORDER _ OR %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _ %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR _ %WS_CLIPCHILDREN OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _ %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT _ OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg #PBFORMS END DIALOG HwndMain = hDlg DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG1 #PBFORMS END CLEANUP FUNCTION = lRslt END FUNCTION '------------------------------------------------------------------------------
So I started looking at what was different, and what is different is my Main program is a MDI Dialog of sorts, so I grabbed "PbNote2" and tried the same test.
Code:
'============================================================================== ' ' PBNOTE2.BAS example for PowerBASIC For Windows ' Copyright (c) 1997-2008 PowerBASIC, Inc. ' All Rights Reserved. ' ' MDI text editor - based on the PBNote sample, but menu, string table and ' accelator code, etc, has been lifted out from resource into this code, ' and a complete PrintDocument procedure has been added. ' ' Note: Windows 95 "thunks down" to the 16-bit GDI for edit boxes, so ' edit boxes are limited to 64k in Windows 95. Edit controls in ' Windows NT have a higher limit, here we set 1,048,576 bytes. ' ' '============================================================================== '------------------------------------------------------------------------------ ' Initial Declares - first eliminate unnecessary functions in COMMCTRL.INC '------------------------------------------------------------------------------ %NOANIMATE = 1 ' Animate control %NOBUTTON = 1 ' Button %NOCOMBO = 1 ' Combo box %NOCOMBOEX = 1 ' ComboBoxEx %NODATETIMEPICK = 1 ' Date/time picker %NODRAGLIST = 1 ' Drag list control %NOEDIT = 1 ' Edit control %NOFLATSBAPIS = 1 ' Flat scroll bar %NOHEADER = 1 ' Header control %NOHOTKEY = 1 ' HotKey control %NOIMAGELIST = 1 ' Image APIs %NOIPADDRESS = 1 ' IP Address edit control %NOLIST = 1 ' List box control %NOLISTVIEW = 1 ' ListView control %NOMENUHELP = 1 ' Menu help %NOMONTHCAL = 1 ' MonthCal %NOMUI = 1 ' MUI %NONATIVEFONTCTL = 1 ' Native Font control %NOPAGESCROLLER = 1 ' Pager %NOPROGRESS = 1 ' Progress control %NOREBAR = 1 ' Rebar control ' %NOSTATUSBAR = 1 ' Status bar %NOTABCONTROL = 1 ' Tab control ' %NOTOOLBAR = 1 ' Tool bar ' %NOTOOLTIPS = 1 ' Tool tips %NOTRACKBAR = 1 ' Track bar %NOTRACKMOUSEEVENT = 1 ' Track Mouse Event %NOTREEVIEW = 1 ' TreeView %NOUPDOWN = 1 ' Up Down arrow control '------------------------------------------------------------------------------ %USEMACROS = 1 ' Use Macros in include files, where possible '------------------------------------------------------------------------------ #COMPILER PBWIN 9 #COMPILE EXE '#RESOURCE "PBNOTE2.PBR" #DIM ALL '------------------------------------------------------------------------------ #INCLUDE "Win32API.inc" ' Win32 API declares and equates, etc. #INCLUDE "CommCtrl.inc" ' Common control declares and equates, etc. #INCLUDE "InitCtrl.inc" ' improved initiation for Common controls #INCLUDE "ComDlg32.inc" ' Common dialog declares and equates, etc. #INCLUDE "MDI32.inc" ' wrappers for some MDI-related calls '------------------------------------------------------------------------------ $PROGRAMCLASSNAME = "PBNote2" ' Main window class $NOTEPADCLASSNAME = "PBNOTE32" ' MDI child class $INIFILENAME = "PBNote2.ini" ' configuration file $HELPFILE = "PBWin.hlp" ' help file (alter name as necessary) '------------------------------------------------------------------------------ %ID_TOOLBAR = %WM_USER + 1024& ' toolbar %ID_STATUSBAR = %WM_USER + 1025& ' statusbar %IDC_EDIT = %WM_USER + 1026& ' edit control ' FILE %IDM_NEW = %WM_USER + 2000& ' New File %IDM_OPEN = %WM_USER + 2001& ' Open File %IDM_SAVE = %WM_USER + 2005& ' Save %IDM_SAVEAS = %WM_USER + 2006& ' Save As %IDM_PRINT = %WM_USER + 2007& ' Print %IDM_EXIT = %WM_USER + 2009& ' Exit %IDM_RECENT1 = %WM_USER + 2010& ' Recently opened file 1 %IDM_RECENT2 = %WM_USER + 2011& ' Recently opened file 2 %IDM_RECENT3 = %WM_USER + 2012& ' Recently opened file 3 %IDM_RECENT4 = %WM_USER + 2013& ' Recently opened file 4 %IDM_RECENT5 = %WM_USER + 2014& ' Recently opened file 5 %IDM_RECENT6 = %WM_USER + 2015& ' Recently opened file 6 %IDM_RECENT7 = %WM_USER + 2016& ' Recently opened file 7 %IDM_RECENT8 = %WM_USER + 2017& ' Recently opened file 8 ' EDIT %IDM_UNDO = %WM_USER + 2030& ' Undo %IDM_CUT = %WM_USER + 2032& ' Cut %IDM_COPY = %WM_USER + 2033& ' Copy %IDM_PASTE = %WM_USER + 2034& ' Paste %IDM_DELETE = %WM_USER + 2035& ' Delete %IDM_SELALL = %WM_USER + 2036& ' Select all ' WINDOW %IDM_CASCADE = %WM_USER + 2060& ' Cascade windows %IDM_TILEH = %WM_USER + 2061& ' Tile windows horizontally %IDM_TILEV = %WM_USER + 2062& ' Tile windows vertically %IDM_ARRANGE = %WM_USER + 2065& ' Arrange icons %IDM_CLOSE = %WM_USER + 2067& ' Close all ' HELP %IDM_ABOUT = %WM_USER + 2086& ' About box '------------------------------------------------------------------------------ GLOBAL g_hInst AS DWORD GLOBAL g_hMenu AS DWORD GLOBAL g_hMenuEdit AS DWORD GLOBAL g_hMenuFile AS DWORD GLOBAL g_hMenuReopen AS DWORD GLOBAL g_hMenuWindow AS DWORD GLOBAL g_hStatus AS DWORD GLOBAL g_hToolbar AS DWORD GLOBAL g_hWndMain AS DWORD GLOBAL g_hWndClient AS DWORD GLOBAL g_fClosed AS LONG GLOBAL g_FreezeMenu AS LONG GLOBAL g_NewComCtl AS CURRENCYX GLOBAL g_NewDocNum AS LONG GLOBAL g_zIni AS ASCIIZ * %MAX_PATH '------------------------------------------------------------------------------ DECLARE FUNCTION MakeAccelerators() AS DWORD DECLARE FUNCTION MakeMenu (BYVAL hWnd AS DWORD) AS DWORD DECLARE FUNCTION MakeToolBar (BYVAL hWnd AS DWORD) AS DWORD DECLARE FUNCTION FileExist (BYVAL sfName AS STRING) 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 FUNCTION GetStringTable (BYVAL ID AS LONG) AS STRING DECLARE FUNCTION IsWin95() AS LONG DECLARE FUNCTION OpenThisFile (BYVAL fn AS STRING) AS DWORD '------------------------------------------------------------------------------ DECLARE SUB GetRecentFiles DECLARE SUB HideButtons (BYVAL HideState AS LONG) DECLARE SUB PrintDocument (BYVAL hEdit AS DWORD) DECLARE SUB SAVEFILE (BYVAL Ask AS LONG) DECLARE SUB WriteRecentFiles (BYVAL OpenFName AS STRING) GLOBAL HwndMain AS LONG '============================================================================== FUNCTION WINMAIN (BYVAL hInstance AS DWORD, _ BYVAL hPrevInstance AS DWORD, _ BYVAL lpCmdLine AS ASCIIZ PTR, _ BYVAL iCmdShow AS LONG) AS LONG '------------------------------------------------------------------------------ ' Program entrance '---------------------------------------------------------------------------- LOCAL hAccel AS DWORD LOCAL Msg AS TAGMSG LOCAL wce AS WNDCLASSEX LOCAL szClassName AS ASCIIZ * 80 g_hInst = hInstance 'store module handle in global variable for later use GetModuleFileName g_hInst, g_zIni, %MAX_PATH ' get path to program g_zIni = LEFT$(g_zIni, INSTR(-1, g_zIni, ANY "\/:")) ' this is same as AppPath g_zIni = g_zIni & $INIFILENAME ' use AppPath for ini file '---------------------------------------------------------------------------- ' Register Main Window Class szClassName = $PROGRAMCLASSNAME wce.cbSize = SIZEOF(wce) wce.STYLE = %CS_HREDRAW OR %CS_VREDRAW wce.lpfnWndProc = CODEPTR(WndProc) wce.cbClsExtra = 0 wce.cbWndExtra = 0 wce.hInstance = g_hInst wce.hIcon = LoadIcon(g_hInst, "APPICON") IF wce.hIcon = 0 THEN 'if no resource icon, give it a system icon.. wce.hIcon = LoadIcon(0, BYVAL %IDI_APPLICATION) END IF wce.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW) wce.hbrBackground = %NULL wce.lpszMenuName = %NULL wce.lpszClassName = VARPTR(szClassName) wce.hIconSm = LoadIcon(g_hInst, BYVAL %IDI_APPLICATION) IF RegisterClassEx(wce) = 0 THEN RegisterClass BYVAL (VARPTR(wce) + 4) END IF '---------------------------------------------------------------------------- ' Register Code Window Class szClassName = $NOTEPADCLASSNAME wce.cbSize = SIZEOF(wce) wce.STYLE = %CS_DBLCLKS OR %CS_HREDRAW OR %CS_VREDRAW wce.lpfnWndProc = CODEPTR(CodeProc) wce.cbClsExtra = 0 wce.cbWndExtra = 4 wce.hInstance = g_hInst wce.hIcon = LoadIcon(g_hInst, "NOTEICON") IF wce.hIcon = 0 THEN 'if no resource icon, give it a system icon.. wce.hIcon = LoadIcon(0, BYVAL %IDI_APPLICATION) END IF wce.hCursor = LoadCursor(%NULL, BYVAL %IDC_IBEAM) wce.hbrBackground = %NULL wce.lpszMenuName = %NULL wce.lpszClassName = VARPTR(szClassName) wce.hIconSm = LoadIcon(g_hInst, BYVAL %IDI_APPLICATION) IF ISFALSE(RegisterClassEx(wce)) THEN RegisterClass BYVAL (VARPTR(wce) + 4) END IF '---------------------------------------------------------------------------- g_hMenu = MakeMenu(g_hWndMain) 'main menu g_hMenuFile = GetSubMenu(g_hMenu, 0) 'File menu g_hMenuReopen = GetSubMenu(g_hMenuFile, 2) 'Reopen files submenu g_hMenuEdit = GetSubMenu(g_hMenu, 1) 'Edit menu g_hMenuWindow = GetSubMenu(g_hMenu, 2) 'Window menu '---------------------------------------------------------------------------- ' Create main window using the registered class g_hWndMain = CreateWindow($PROGRAMCLASSNAME, _ ' Main window's class name $PROGRAMCLASSNAME, _ ' Main window's initial caption %WS_OVERLAPPEDWINDOW, _ ' window style (GetSystemMetrics(%SM_CXSCREEN) - 640) / 2, _ ' initial x position (GetSystemMetrics(%SM_CYSCREEN) - 480) / 2, _ ' initial y position 640, _ ' initial x size 480, _ ' initial y size %NULL, _ ' parent window handle g_hMenu, _ ' window menu handle g_hInst, _ ' program instance handle BYVAL %NULL) ' creation parameters '---------------------------------------------------------------------------- hAccel = MakeAccelerators() GetRecentFiles ' fill the Recent files menu (MRU) .. HideButtons %TRUE ShowWindow g_hWndMain, iCmdShow UpdateWindow g_hWndMain HwndMain = g_hWndMain '---------------------------------------------------------------------------- ' Message handler loop WHILE GetMessage(Msg, BYVAL %NULL, 0, 0) IF TranslateMDISysAccel(g_hWndClient, Msg) = 0 THEN IF TranslateAccelerator(g_hWndMain, hAccel, Msg) = 0 THEN TranslateMessage Msg DispatchMessage Msg END IF END IF WEND FUNCTION = msg.wParam END FUNCTION ' end WinMain '============================================================================== FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, _ BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG '------------------------------------------------------------------------------ ' Main procedure '---------------------------------------------------------------------------- LOCAL ToolHeight AS LONG LOCAL StatHeight AS LONG LOCAL dwProc AS DWORD LOCAL hLib AS DWORD LOCAL hMdi AS DWORD LOCAL STYLE AS DWORD LOCAL f AS STRING LOCAL PATH AS STRING LOCAL pt AS POINTAPI LOCAL tRect AS RECT LOCAL mii AS MENUITEMINFO LOCAL tbn AS TBNOTIFY PTR LOCAL lpToolTip AS TOOLTIPTEXT PTR LOCAL cc AS CLIENTCREATESTRUCT LOCAL iccex AS INIT_COMMON_CONTROLSEX LOCAL zText AS ASCIIZ * %MAX_PATH SELECT CASE AS LONG wMsg CASE %WM_CREATE ' Create the MDI Client window cc.idFirstChild = 1 cc.hWindowMenu = g_hMenuWindow 'for file list in Window menu g_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, 1, g_hInst, cc) '------------------------------------------------------------------------ ' some of CommCtrl.dll's controls, messages and styles were not included ' in standard Win95A release, so we need to see how to initiate the dll. '------------------------------------------------------------------------ g_NewComCtl = InitComctl32 (%ICC_BAR_CLASSES) '------------------------------------------------------------------------ ' Create the status bar g_hStatus = CreateStatusWindow (%WS_CHILD OR %WS_VISIBLE OR %SBS_SIZEGRIP, _ "", hWnd, %ID_STATUSBAR) 'set up a couple of statusbar parts DIM prts(1) AS LONG prts(0) = 250 : prts(1) = -1 Sendmessage g_hStatus, %SB_SETPARTS, 2, VARPTR(prts(0)) SendMessage g_hStatus, %SB_SETTEXT, 0, VARPTR(zText) '------------------------------------------------------------------------ g_hToolbar = MakeToolBar (hWnd) EXIT FUNCTION CASE %WM_SIZE IF wParam <> %SIZE_MINIMIZED THEN LOCAL HwndMainRect AS RECT LOCAL x AS LONG LOCAL y AS LONG LOCAL xx AS LONG LOCAL yy AS LONG '*** Get Toolbar and statusbar height GetWindowRect HwndMain, HwndMainRect MSGBOX STR$(HwndMainRect.nLeft) + "," + STR$(HwndMainRect.nBottom) DIALOG PIXELS HwndMain, HwndMainRect.nLeft, HwndMainRect.nBottom TO UNITS HwndMainRect.nLeft, HwndMainRect.nBottom MSGBOX STR$(HwndMainRect.nLeft) + "," + STR$(HwndMainRect.nBottom) 'MSGBOX STR$(xx) + "," + STR$(yy) GetWindowRect g_hToolbar, tRect ToolHeight = tRect.nBottom - tRect.nTop 'toolbar height GetWindowRect g_hStatus, tRect StatHeight = tRect.nBottom - tRect.nTop 'statusbar height SendMessage g_hStatus, wMsg, wParam, lParam SendMessage g_hToolbar, wMsg, wParam, lParam MoveWindow g_hWndClient, -2, ToolHeight, LO(WORD, lParam) + 4, _ HI(WORD, lParam) - (ToolHeight + StatHeight), %TRUE END IF EXIT FUNCTION CASE %WM_NOTIFY tbn = lParam IF @tbn.hdr.code = %TTN_NEEDTEXT THEN lpToolTip = lParam zText = GetStringTable(@lpToolTip.hdr.idFrom) @lpToolTip.lpszText = VARPTR(zText) ELSEIF g_NewComCtl >= 4.7 AND @tbn.hdr.code = %TBN_DROPDOWN THEN SELECT CASE AS LONG @tbn.iItem CASE %IDM_OPEN SendMessage @tbn.hdr.hwndFrom, %TB_GETRECT, @tbn.iItem, VARPTR(tRect) MapWindowPoints @tbn.hdr.hwndFrom, %HWND_DESKTOP, BYVAL VARPTR(tRect), 2 TrackPopupMenu g_hMenuReopen, 0, tRect.nLeft, tRect.nBottom, 0, hWnd, BYVAL %NULL END SELECT END IF EXIT FUNCTION CASE %WM_MENUSELECT zText = GetStringTable(LOWRD(wParam)) SendMessage g_hStatus, %SB_SETTEXT, 0, VARPTR(zText) EXIT FUNCTION CASE %WM_NCPAINT 'if flag is set, return zero to avoid menu update IF g_FreezeMenu THEN EXIT FUNCTION CASE %WM_COMMAND SELECT CASE AS LONG LO(WORD, wParam) CASE %IDM_NEW IF MdiGetActive(g_hWndClient) AND _ 'if not first doc and docs are maximized IsZoomed(MdiGetActive(g_hWndClient)) THEN g_FreezeMenu = 1 hMdi = CreateMdiChild($NOTEPADCLASSNAME, g_hWndClient, "", %WS_MAXIMIZE) IF g_FreezeMenu THEN 'now time to redraw menu g_FreezeMenu = 0 DrawMenuBar g_hWndMain END IF EXIT FUNCTION CASE %IDM_OPEN PATH = CURDIR$ f = "*.txt" STYLE = %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY OR %OFN_LONGNAMES IF OpenFileDialog(g_hWndMain, "", f, PATH, _ "Text Files|*.txt|All Files|*.*", "txt", STYLE) THEN InvalidateRect g_hToolbar, BYVAL 0, 0 UpdateWindow g_hToolbar OpenThisFile f EXIT FUNCTION END IF CASE %IDM_RECENT1 TO %IDM_RECENT8 'MRU menu items (file names) IF IsWin95 THEN mii.cbSize = LEN(mii) - 4 'size of structure mii.fMask = %MIIM_TYPE OR %MIIM_ID 'set mask ELSE mii.cbSize = LEN(mii) 'size of structure mii.fMask = %MIIM_FTYPE OR %MIIM_ID OR %MIIM_STRING 'set mask END IF mii.fType = %MFT_STRING mii.wID = LO(WORD, wParam) 'selected item mii.cch = %MAX_PATH 'max length of string f = SPACE$(%MAX_PATH) 'allocate enough string space mii.dwTypeData = STRPTR(f) 'point to allocated string GetMenuItemInfo g_hMenuReopen,mii.wID,0&,mii 'get string f = EXTRACT$(f, CHR$(0)) 'cut at zero ending f = MID$(f, 4) 'remove first part - item number OpenThisFile f 'open selected file CASE %IDM_SAVE : SAVEFILE %FALSE CASE %IDM_SAVEAS : SAVEFILE %TRUE CASE %IDM_PRINT : PrintDocument GetEdit CASE %IDM_EXIT : SendMessage hWnd, %WM_CLOSE, wParam, lParam CASE %IDM_UNDO : SendMessage GetEdit, %EM_UNDO, 0, 0 CASE %IDM_CUT : SendMessage GetEdit, %WM_CUT, 0, 0 CASE %IDM_COPY : SendMessage GetEdit, %WM_COPY, 0, 0 CASE %IDM_PASTE : SendMessage GetEdit, %WM_PASTE, 0, 0 CASE %IDM_DELETE : SendMessage GetEdit, %WM_CLEAR, 0, 0 CASE %IDM_SELALL : SendMessage GetEdit, %EM_SETSEL, 0, -1 CASE %IDM_CASCADE : MdiCascade (g_hWndClient) CASE %IDM_TILEH : MdiTile (g_hWndClient, %MDITILE_HORIZONTAL) CASE %IDM_TILEV : MdiTile (g_hWndClient, %MDITILE_VERTICAL) CASE %IDM_ARRANGE : MdiIconArrange (g_hWndClient) CASE %IDM_CLOSE WHILE MdiGetActive(g_hWndClient) CALL SendMessage(MdiGetActive(g_hWndClient), %WM_CLOSE, 0, 0) IF g_fClosed = 0 THEN EXIT FUNCTION WEND CASE %IDHELP WinHelp hWnd, $HELPFILE, %HELP_INDEX, 0& '<- to show a help file CASE %IDM_ABOUT ' Example of how to show Windows built-in AboutDlg ShellAbout hWnd, "PBNote2 v1.0#", _ "PowerBASIC example - MDI text editor", _ LoadIcon(g_hInst, "APPICON") END SELECT CASE %WM_CLOSE WHILE MdiGetActive(g_hWndClient) CALL SendMessage(MdiGetActive(g_hWndClient), %WM_CLOSE, 0, 0) IF g_fClosed = 0 THEN EXIT FUNCTION WEND CASE %WM_DESTROY PostQuitMessage 0 EXIT FUNCTION CASE %WM_HELP WinHelp hWnd, $HELPFILE, %HELP_INDEX, 0& '<- to show a help file CASE %WM_SYSCOLORCHANGE ' Forward this message to common controls so that they will ' be properly updated if a user changes system color settings. SendMessage g_hToolbar, %WM_SYSCOLORCHANGE, wParam, lParam SendMessage g_hStatus, %WM_SYSCOLORCHANGE, wParam, lParam END SELECT FUNCTION = DefFrameProc(hWnd, g_hWndClient, wMsg, wParam, lParam) END FUNCTION '============================================================================== FUNCTION CodeProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, _ BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG '------------------------------------------------------------------------------ ' NotePad procedure - handle messages from the MDI child windows. '---------------------------------------------------------------------------- LOCAL nFile AS LONG LOCAL dwRes AS DWORD LOCAL hEdit AS DWORD LOCAL hFont AS DWORD LOCAL Buffer AS STRING LOCAL pt AS POINTAPI LOCAL rc AS RECT LOCAL zText AS ASCIIZ * %MAX_PATH SELECT CASE AS LONG wMsg CASE %WM_CREATE GetClientRect hWnd, rc hEdit = CreateWindowEx(0, "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, rc.nRight, rc.nBottom, hWnd, %IDC_EDIT, g_hInst, BYVAL %NULL) ' set a fixed width font in the edit control hFont = GetStockObject(%ANSI_FIXED_FONT) IF hFont THEN SendMessage hEdit, %WM_SETFONT, hFont, 0 ' 32/64 Kb byte limit in Win95/98, but 1 MB limit in NT? SendMessage hEdit, %EM_SETLIMITTEXT, &H100000&, 0 GetWindowText hWnd, zText, SIZEOF(zText) IF LEN(zText) THEN nFile = FREEFILE OPEN zText FOR BINARY AS nFile LEN = 8192 IF ERR THEN BEEP DestroyWindow hWnd EXIT FUNCTION END IF GET$ nFile, LOF(nFile), Buffer CLOSE nFile SetWindowText hEdit, BYVAL STRPTR(Buffer) WriteRecentFiles zText ' refresh reopen file list ELSE INCR g_NewDocNum SetWindowText hWnd, "Untitled" & STR$(g_NewDocNum) END IF IF MdiGetActive(g_hWndClient) = 0 THEN HideButtons 0 'if first doc EXIT FUNCTION CASE %WM_SIZE IF wParam <> %SIZE_MINIMIZED THEN hEdit = GetDlgItem(hWnd, %IDC_EDIT) MoveWindow hEdit, 0, 0, LOWRD(lParam), HIWRD(lParam), 1 SendMessage hEdit, %EM_GETRECT, 0, VARPTR(rc) 'for margins in editor rc.nTop = 2 ' pixels, top margin rc.nLeft = 3 ' pixels, left margin rc.nBottom = rc.nBottom + 2 ' increase bottom part a bit SendMessage hEdit, %EM_SETRECTNP, 0, BYVAL VARPTR(rc) END IF CASE %WM_SETFOCUS SetFocus GetEdit EXIT FUNCTION CASE %WM_CLOSE IF SendMessage(GetEdit, %EM_GETMODIFY, 0, 0) THEN GetWindowText hWnd, zText, SIZEOF(zText) Buffer = "Save changes to " & FileNam(zText) & " ?" dwRes = MessageBox(hWnd, BYVAL STRPTR(Buffer), "Save file", _ %MB_YESNOCANCEL OR %MB_ICONEXCLAMATION) IF dwRes = %IDCANCEL THEN g_fClosed = %FALSE EXIT FUNCTION ELSEIF dwRes = %IDYES THEN SAVEFILE %FALSE END IF END IF g_fClosed = %TRUE dwRes = GetWindow(g_hWndClient, %GW_CHILD) IF GetWindow(dwRes, %GW_HWNDNEXT) = 0 THEN 'if this is last doc HideButtons %TRUE END IF CASE %WM_DESTROY IF MdiGetActive(g_hWndClient) = 0 THEN 'if last one closed g_NewDocNum = 0 'reset doc counter END IF END SELECT FUNCTION = DefMDIChildProc(hWnd, wMsg, wParam, lParam) END FUNCTION '============================================================================== FUNCTION FileExist(BYVAL sfName AS STRING) AS LONG '------------------------------------------------------------------------------ ' FileExist - make sure a file or folder exists '---------------------------------------------------------------------------- LOCAL hRes AS DWORD, tWFD AS WIN32_FIND_DATA IF LEN(sfName) = 0 THEN EXIT FUNCTION 'no need to continue then.. IF ASC(sfName, -1) = 92 THEN 'if a path with trailing backslash sfName = LEFT$(sfName, LEN(sfName) - 1) 'remove trailing backslash END IF '---------------------------------------------------------------------------- hRes = FindFirstFile(BYVAL STRPTR(sfName), tWFD) IF hRes <> %INVALID_HANDLE_VALUE THEN FUNCTION = %TRUE FindClose hRes END IF END FUNCTION '============================================================================== FUNCTION FileNam (BYVAL Src AS STRING) AS STRING '------------------------------------------------------------------------------ ' Get file name part of given path & name '---------------------------------------------------------------------------- LOCAL x AS LONG x = INSTR(-1, Src, ANY ":/\") IF x THEN FUNCTION = MID$(Src, x + 1) ELSE FUNCTION = Src END IF END FUNCTION '============================================================================== FUNCTION FilePath (BYVAL Src AS STRING) AS STRING '------------------------------------------------------------------------------ ' Get path -part of given path & name '---------------------------------------------------------------------------- LOCAL x AS LONG x = INSTR(-1, Src, ANY ":\/") IF x THEN FUNCTION = LEFT$(Src, x) ELSE FUNCTION = Src END IF END FUNCTION '============================================================================== FUNCTION GetEdit() AS LONG '------------------------------------------------------------------------------ ' Get active MDI child's edit control, if any '---------------------------------------------------------------------------- FUNCTION = GetDlgItem(MdiGetActive(g_hWndClient), %IDC_EDIT) END FUNCTION '============================================================================== SUB GetRecentFiles '------------------------------------------------------------------------------ ' Read the list of recently opened files and rebuild the Recent files submenu '---------------------------------------------------------------------------- LOCAL Bc AS LONG, lRes AS LONG LOCAL InString AS ASCIIZ * 300 LOCAL zSection AS ASCIIZ * 30, zKey AS ASCIIZ * 30, zDefault AS ASCIIZ * 30 '---------------------------------------------------------------------------- ' First clear the Recent file submenu from all items '---------------------------------------------------------------------------- FOR Bc = 1 TO GetMenuItemCount(g_hMenuReopen) MENU DELETE g_hMenuReopen, 1 NEXT Bc '---------------------------------------------------------------------------- ' Then Rebuild it with items via file names stored in the ini file '---------------------------------------------------------------------------- Bc = 1 zSection = "Reopen files" DO zKey = "File " & FORMAT$(Bc) lRes = GetPrivateProfileString(zSection, zKey, zDefault, InString, %MAX_PATH, g_zIni) IF lRes THEN InString = "&" & FORMAT$(Bc) & " " & LEFT$(InString, lRes) MENU ADD STRING, g_hMenuReopen, InString, %IDM_RECENT1 + Bc - 1, %MF_ENABLED ELSE EXIT DO END IF INCR Bc IF Bc > 8 THEN EXIT DO LOOP END SUB '============================================================================== FUNCTION GetStringTable(BYVAL ID AS LONG) AS STRING '------------------------------------------------------------------------------ ' Return a id related string table text '---------------------------------------------------------------------------- SELECT CASE AS LONG ID CASE %IDM_NEW : FUNCTION = " Open a new document" CASE %IDM_OPEN : FUNCTION = " Open an existing file" CASE %IDM_SAVE : FUNCTION = " Save file directly" CASE %IDM_SAVEAS : FUNCTION = " Save file via dialog" CASE %IDM_PRINT : FUNCTION = " Print active document" CASE %IDM_EXIT : FUNCTION = " Close PBNote2" CASE %IDM_UNDO : FUNCTION = " Undo last action" CASE %IDM_CUT : FUNCTION = " Cut to clipboard" CASE %IDM_COPY : FUNCTION = " Copy to clipboard" CASE %IDM_PASTE : FUNCTION = " Paste from clipboard" CASE %IDM_DELETE : FUNCTION = " Delete selected text" CASE %IDM_SELALL : FUNCTION = " Select all text" CASE %IDM_CASCADE : FUNCTION = " Cascade windows" CASE %IDM_TILEH : FUNCTION = " Tile windows horizontally" CASE %IDM_TILEV : FUNCTION = " Tile windows vertically" CASE %IDM_ARRANGE : FUNCTION = " Arrange minimized windows" CASE %IDM_CLOSE : FUNCTION = " Close all windows" CASE %IDHELP : FUNCTION = " Show help file" CASE %IDM_ABOUT : FUNCTION = " About PBNote2" END SELECT END FUNCTION '============================================================================== SUB HideButtons (BYVAL HideState AS LONG) '------------------------------------------------------------------------------ ' Show/hide buttons and enable/disable menus '---------------------------------------------------------------------------- LOCAL ITEM AS DWORD, mFlag AS DWORD IF GetSubMenu(g_hMenu, 0) = g_hMenuFile THEN ITEM = 1 ELSE ITEM = 2 IF HideState THEN mFlag = %MF_GRAYED ELSE mFlag = %MF_ENABLED EnableMenuItem g_hMenu, ITEM, %MF_BYPOSITION OR mFlag EnableMenuItem g_hMenu, ITEM + 1, %MF_BYPOSITION OR mFlag EnableMenuItem g_hMenuFile, %IDM_SAVE, %MF_BYCOMMAND OR mFlag EnableMenuItem g_hMenuFile, %IDM_SAVEAS, %MF_BYCOMMAND OR mFlag EnableMenuItem g_hMenuFile, %IDM_PRINT, %MF_BYCOMMAND OR mFlag DrawMenuBar g_hWndMain SendMessage g_hToolbar, %TB_HIDEBUTTON, %IDM_UNDO, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, 703, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, %IDM_PASTE, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, %IDM_COPY, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, %IDM_CUT, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, 702, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, %IDM_PRINT, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, 701, HideState SendMessage g_hToolbar, %TB_HIDEBUTTON, %IDM_SAVE, HideState END SUB '============================================================================== FUNCTION IsWin95() AS LONG '------------------------------------------------------------------------------ ' Return true if OS is Windows 95 '---------------------------------------------------------------------------- LOCAL vi AS OSVERSIONINFO vi.dwOsVersionInfoSize = SIZEOF(vi) GetVersionEx vi FUNCTION = ((vi.dwPlatformId = %VER_PLATFORM_WIN32_WINDOWS) AND (vi.dwMinorVersion = 0)) END FUNCTION '============================================================================== FUNCTION MakeAccelerators() AS DWORD '------------------------------------------------------------------------------ ' Create an Accelerator table for keyboard shortcuts '----------------------------------------------------------------------------- DIM c AS LONG, ac(9) AS ACCELAPI ' for keyboard accelator table values ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_O : ac(c).cmd = %IDM_OPEN : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_N : ac(c).cmd = %IDM_NEW : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_S : ac(c).cmd = %IDM_SAVE : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_P : ac(c).cmd = %IDM_PRINT : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_Z : ac(c).cmd = %IDM_UNDO : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_X : ac(c).cmd = %IDM_CUT : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_C : ac(c).cmd = %IDM_COPY : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_V : ac(c).cmd = %IDM_PASTE : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_A : ac(c).cmd = %IDM_SELALL : INCR c ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key = %VK_Q : ac(c).cmd = %IDM_EXIT : INCR c FUNCTION = CreateAcceleratorTable(ac(0), UBOUND(ac)) END FUNCTION '============================================================================== FUNCTION MakeMenu (BYVAL hWnd AS DWORD) AS DWORD '------------------------------------------------------------------------------ ' Create a menu '---------------------------------------------------------------------------- LOCAL hMnu AS DWORD, hSubMenu AS DWORD, hSubMenu2 AS DWORD MENU NEW BAR TO hMnu MENU NEW POPUP TO hSubMenu MENU ADD POPUP, hMnu, "&File", hSubMenu, %MF_ENABLED MENU ADD STRING, hSubMenu, "&New" + $TAB + "Ctrl+N", %IDM_NEW, %MF_ENABLED MENU ADD STRING, hSubMenu, "&Open" + $TAB + "Ctrl+O", %IDM_OPEN, %MF_ENABLED MENU NEW POPUP TO hSubMenu2 MENU ADD POPUP, hSubMenu, "&Reopen...", hSubMenu2, %MF_ENABLED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "&Save" + $TAB + "Ctrl+S", %IDM_SAVE, %MF_GRAYED MENU ADD STRING, hSubMenu, "Save &As", %IDM_SAVEAS, %MF_GRAYED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "&Print.." + $TAB + "Ctrl+P", %IDM_PRINT, %MF_GRAYED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "E&xit" + $TAB + "Alt+F4", %IDM_EXIT, %MF_ENABLED MENU NEW POPUP TO hSubMenu MENU ADD POPUP, hMnu, "&Edit", hSubMenu, %MF_GRAYED MENU ADD STRING, hSubMenu, "Undo" + $TAB + "Ctrl+Z", %IDM_UNDO, %MF_ENABLED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "Cut" + $TAB + "Ctrl+X", %IDM_CUT, %MF_ENABLED MENU ADD STRING, hSubMenu, "Copy" + $TAB + "Ctrl+C", %IDM_COPY, %MF_ENABLED MENU ADD STRING, hSubMenu, "Paste" + $TAB + "Ctrl+V", %IDM_PASTE, %MF_ENABLED MENU ADD STRING, hSubMenu, "Delete" + $TAB + "Delete", %IDM_DELETE, %MF_ENABLED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "Select &all" + $TAB + "Ctrl+A", %IDM_SELALL, %MF_ENABLED MENU NEW POPUP TO hSubMenu MENU ADD POPUP, hMnu, "&Window", hSubMenu, %MF_GRAYED MENU ADD STRING, hSubMenu, "&Cascade", %IDM_CASCADE, %MF_ENABLED MENU ADD STRING, hSubMenu, "&Tile horizontally", %IDM_TILEH, %MF_ENABLED MENU ADD STRING, hSubMenu, "&Tile vertically", %IDM_TILEV, %MF_ENABLED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "Arrange &Icons", %IDM_ARRANGE, %MF_ENABLED MENU ADD STRING, hSubMenu, "Close &All", %IDM_CLOSE, %MF_ENABLED MENU NEW POPUP TO hSubMenu MENU ADD POPUP, hMnu, "&Help", hSubMenu, %MF_ENABLED MENU ADD STRING, hSubMenu, "&Help", %IDHELP, %MF_ENABLED MENU ADD STRING, hSubMenu, "-", 0, 0 MENU ADD STRING, hSubMenu, "&About", %IDM_ABOUT, %MF_ENABLED FUNCTION = hMnu END FUNCTION '============================================================================== FUNCTION MakeToolBar (BYVAL hWnd AS DWORD) AS DWORD '------------------------------------------------------------------------------ ' Setup and create the ToolBar '---------------------------------------------------------------------------- LOCAL c AS LONG, hToolBar AS DWORD DIM tbb(10) AS TBBUTTON 'for 11 buttons, including separators ' Fill the TBBUTTON array with button information tbb(c).iBitmap = %STD_FILENEW tbb(c).idCommand = %IDM_NEW tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c tbb(c).iBitmap = %STD_FILEOPEN tbb(c).idCommand = %IDM_OPEN tbb(c).fsState = %TBSTATE_ENABLED IF g_NewComCtl >= 4.7 THEN tbb(c).fsStyle = %TBSTYLE_DROPDOWN ELSE tbb(c).fsStyle = %TBSTYLE_BUTTON END IF INCR c tbb(c).iBitmap = %STD_FILESAVE tbb(c).idCommand = %IDM_SAVE tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c tbb(c).iBitmap = 0 tbb(c).idCommand = 701 tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_SEP INCR c tbb(c).iBitmap = %STD_PRINT tbb(c).idCommand = %IDM_PRINT tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c tbb(c).iBitmap = 0 tbb(c).idCommand = 702 tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_SEP INCR c tbb(c).iBitmap = %STD_CUT tbb(c).idCommand = %IDM_CUT tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c tbb(c).iBitmap = %STD_COPY tbb(c).idCommand = %IDM_COPY tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c tbb(c).iBitmap = %STD_PASTE tbb(c).idCommand = %IDM_PASTE tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c tbb(c).iBitmap = 0 tbb(c).idCommand = 703 tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_SEP INCR c tbb(c).iBitmap = %STD_UNDO tbb(c).idCommand = %IDM_UNDO tbb(c).fsState = %TBSTATE_ENABLED tbb(c).fsStyle = %TBSTYLE_BUTTON INCR c hToolBar = CreateToolbarEx (hWnd, %WS_CHILD OR %WS_VISIBLE OR %TBSTYLE_TOOLTIPS, _ %ID_TOOLBAR, 12, %HINST_COMMCTRL, %IDB_STD_SMALL_COLOR, _ tbb(0), UBOUND(tbb) + 1, 0, 0, 16, 15, LEN(TBBUTTON)) IF hToolBar THEN SendMessage hToolBar, %TB_AUTOSIZE, 0, 0 IF g_NewComCtl >= 4.7 THEN ' then we can use more modern features, like flat style, etc. SetWindowLong hToolBar, %GWL_STYLE, _ GetWindowLong(hToolbar, %GWL_STYLE) OR %TBSTYLE_FLAT SendMessage hToolBar, %TB_SETEXTENDEDSTYLE, 0, %TBSTYLE_EX_DRAWDDARROWS END IF END IF FUNCTION = hToolBar END FUNCTION '============================================================================== FUNCTION OpenThisFile(BYVAL fn AS STRING) AS DWORD '------------------------------------------------------------------------------ ' Open file procedure '---------------------------------------------------------------------------- LOCAL hMdi AS DWORD, zText AS ASCIIZ * %MAX_PATH hMdi = GetWindow(g_hWndClient, %GW_CHILD) 'first look at already opened docs WHILE hMdi GetWindowText hMdi, zText, %MAX_PATH IF UCASE$(zText) = UCASE$(fn) THEN 'if already opened SendMessage g_hWndClient, %WM_MDIACTIVATE, hMdi, 0 'activate it WriteRecentFiles fn 'update MRU menu and exit EXIT FUNCTION END IF hMdi = GetWindow(hMdi, %GW_HWNDNEXT) WEND '------------------------------------------------------------------------------ IF MdiGetActive(g_hWndClient) AND _ 'if not first doc and docs are maximized IsZoomed(MdiGetActive(g_hWndClient)) THEN g_FreezeMenu = 1 'turn off menu redraw hMdi = CreateMdiChild($NOTEPADCLASSNAME, g_hWndClient, fn, %WS_MAXIMIZE) IF g_FreezeMenu THEN 'if menu redraw was turned off g_FreezeMenu = 0 'reset flag DrawMenuBar g_hWndMain 'and redraw menu END IF FUNCTION = hMdi END FUNCTION '============================================================================== FUNCTION GetLineText (BYVAL hEdit AS DWORD, BYVAL ln AS LONG) AS STRING '------------------------------------------------------------------------------ ' Get desired line of text from the edit control '---------------------------------------------------------------------------- LOCAL lnStart, lnLen AS LONG, Buf AS STRING lnStart = SendMessage(hEdit, %EM_LINEINDEX, ln, 0) 'line start lnLen = SendMessage(hEdit, %EM_LINELENGTH, lnStart, 0) 'line length IF lnLen THEN Buf = SPACE$(lnLen) lnLen = SendMessage(hEdit, %EM_GETLINE, ln, STRPTR(Buf)) 'Get line IF lnLen THEN FUNCTION = Buf END IF END FUNCTION '============================================================================== SUB PrintDocument (BYVAL hEdit AS DWORD) '------------------------------------------------------------------------------ ' Basic print procedure - prints the contents of an edit control (TextBox) ' with 0.8 inch margins (about 20 mm) and a header at top of each page. '---------------------------------------------------------------------------- LOCAL c, x, y, x1, y1, x2, y2, w, h, w1, h1, pgNum, ppiX, ppiY AS LONG LOCAL sHeader AS STRING LOCAL zDocName AS ASCIIZ * %MAX_PATH '---------------------------------------------------------------------------- ' Grab document title (file name) for the header GetWindowText MdiGetActive(g_hWndClient), zDocName, SIZEOF(zDocName) zDocName = FileNam(zDocName) '---------------------------------------------------------------------------- ERRCLEAR XPRINT ATTACH CHOOSE, "PBNote2 - " + TRIM$(zDocName) ' Attach the default host printer IF ERR = 0 AND LEN(XPRINT$) THEN ' On success XPRINT GET SIZE TO w, h ' Get page size in pixels XPRINT GET MARGIN TO x1, y1, x2, y2 ' Get printer margins XPRINT GET PPI TO ppiX, ppiY ' Get resolution in pixels/inch ' (For resolution in pixels/centimeter, divide ppiX and ppiY with 25.4) x1 = 0.8 * (ppiX - x1) ' 0.8 inch user-defined left margin y1 = 0.8 * (ppiY - y1) ' 0.8 inch user-defined top margin XPRINT FONT "Courier New", 10, 0 ' Set a 10 p fixed-width font GOSUB PrintPageHeader ' Begin by printing a header y2 = h - (0.8 * ppiY) - y2 - h1 ' calculate the bottom margin pos '------------------------------------------------------------------------ FOR c = 0 TO SendMessage(hEdit, %EM_GETLINECOUNT, 0, 0) - 1 XPRINT GET POS TO x, y ' check position IF y > y2 THEN ' if we end up below bottom margin pos XPRINT FORMFEED ' eject paper and start new page GOSUB PrintPageHeader ' Print header part ELSE XPRINT SET POS (x1, y) ' else simply set position END IF XPRINT GetLineText(hEdit, c) ' and print line NEXT '------------------------------------------------------------------------ XPRINT CLOSE ' End printjob and detach the printer END IF EXIT SUB '-------------------------------------------------------------------- PrintPageHeader: INCR pgNum ' print a right-aligned header at top of page sHeader = TRIM$(zDocName) + " - Page" + STR$(pgNum) XPRINT TEXT SIZE sHeader TO w1, h1 XPRINT SET POS (w - w1 - x1, 0.3 * y1) XPRINT sHeader y = y1 XPRINT SET POS (x1, y) ' set position for actual text RETURN END SUB '============================================================================== SUB SAVEFILE (BYVAL Ask AS LONG) '------------------------------------------------------------------------------ ' Save as -procedure '---------------------------------------------------------------------------- LOCAL dwStyle AS DWORD LOCAL nFile AS DWORD LOCAL PATH AS STRING LOCAL f AS STRING LOCAL Buffer AS STRING LOCAL zText AS ASCIIZ * %MAX_PATH '---------------------------------------------------------------------------- GetWindowText MdiGetActive(g_hWndClient), zText, SIZEOF(zText) IF INSTR(zText, ANY ":\/") = 0 THEN 'if no path, it's a new doc (Untitled 1, etc) PATH = CURDIR$ IF RIGHT$(PATH, 1) <> "\" THEN PATH = PATH + "\" f = REMOVE$(zText, " ") & ".txt" 'suggest this name - remove space Ask = %TRUE 'we need the dialog for new docs ELSE PATH = FilePath(zText) f = FileNam(zText) END IF dwStyle = %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY OR _ %OFN_EXPLORER OR %OFN_OVERWRITEPROMPT '---------------------------------------------------------------------------- IF Ask THEN IF SaveFileDialog(g_hWndMain, "", f, PATH, _ "Text Files|*.txt|All Files|*.*", "txt", dwStyle) = 0 THEN EXIT SUB ELSE f = PATH & f END IF '---------------------------------------------------------------------------- nFile = FREEFILE 'time to save the file OPEN f FOR BINARY AS nFile IF ERR THEN ' if something went wrong MSGBOX "Following error occured while trying to save the file:" + $CRLF + _ "Error:" + STR$(ERR) + ", " + ERROR$(ERR)+ $CRLF + $CRLF + _ "The file could not be saved.", _ %MB_ICONWARNING OR %MB_OK OR %MB_TASKMODAL, _ "Save file error!" EXIT SUB END IF Buffer = SPACE$(GetWindowTextLength(GetEdit) + 1) GetWindowText GetEdit, BYVAL STRPTR(Buffer), LEN(Buffer) PUT$ nFile, LEFT$(Buffer, LEN(Buffer) - 1) SETEOF nFile CLOSE nFile '---------------------------------------------------------------------------- IF Ask THEN 'if dialog, update caption in case name was changed SetWindowText MdiGetActive(g_hWndClient), BYVAL STRPTR(f) END IF SendMessage GetEdit, %EM_SETMODIFY, 0, 0 WriteRecentFiles f 'finally, update reopen file list (MRU menu) END SUB '============================================================================== SUB WriteRecentFiles (BYVAL OpenFName AS STRING) '------------------------------------------------------------------------------ ' Save the list of recently opened files '---------------------------------------------------------------------------- LOCAL Ac AS LONG, dwRes AS DWORD, zText AS ASCIIZ * %MAX_PATH LOCAL zSection AS ASCIIZ * 30, zKey AS ASCIIZ * 30, zDefault AS ASCIIZ * 30 DIM IniName(1 : 8) AS STRING zSection = "Reopen files" ' Read current Recent files list from ini file into an array FOR Ac = 1 TO 8 zKey = "File " & FORMAT$(Ac) dwRes = GetPrivateProfileString(zSection, zKey, zDefault, zText, %MAX_PATH, g_zIni) IF dwRes THEN IniName(Ac) = LEFT$(zText, dwRes) NEXT Ac ' Compare existing Recent file names with current file Ac = 0 ARRAY SCAN IniName(), COLLATE UCASE, = UCASE$(OpenFName), TO Ac IF Ac THEN ARRAY DELETE IniName(Ac) ARRAY INSERT IniName(), OpenFName ' Save the array to ini file FOR Ac = 1 TO 8 IF LEN(IniName(Ac)) THEN zKey = "File " & FORMAT$(Ac) zText = IniName(Ac) WritePrivateProfileString zSection, zKey, zText, g_zIni END IF NEXT Ac GetRecentFiles 'update MRU menu END SUB
My only clues at the time are DDT vs SDK, or MDI vs SDI, or SOMETHING I am overlooking?????
My only clue is the offending line is " DIALOG PIXELS HwndMain, HwndMainRect.nLeft, HwndMainRect.nBottom TO UNITS HwndMainRect.nLeft, HwndMainRect.nBottom
"
and it does not matter if I change the "HwndMainRect.nLeft, HwndMainRect.nBottom" to xx, yy so I am at a loss????

Comment