home *** CD-ROM | disk | FTP | other *** search
- Unit DialogWn;
- { Unit: DialogWn
- Version: 1.31
- Purpose: make a descendant of tWindow named tDialogWindow that behaves like
- a modeless or modal dialog.
- Developer: Peter Sawatzki (ps)
- Buchenhof 3, D58091 Hagen, Germany
- CompuServe: 100031,3002
-
- Date: Author:
- 04/22/92 ps initial release by ps
- 07/25/92 ps/jwp added Scroller support
- 08/01/92 ps added RunModal and modal support
- 08/12/92 ps removed SetClassName and NewClass, fixed bug in MDI support
- 08/14/92 ps fixed Focus problems in MDI, give focus to first ws_TabStop child
- 08/30/92 ps fixed more focus problems in MDI, added SysModal support
- 09/27/92 ps call DefDlgProc to support DropDownBoxes and Multiline edit controls
- 10/21/92 ps some changes for new OWL
- 01/28/93 ps add LoadMenu for automatic menu load
- 02/06/93 ps add support for InitResource, fix BWCC's WM_NCCREATE glitch
- 06/10/93 ps added CanClose method to cancel modal dialogs
- 06/15/93 dob removed CanClose, added WMQueryEndSession
- 06/17/93 dob/ps added wmKillFocus and wmNCActivate methods, modified wmSetFocus method
- 06/29/93 ps added tAdvApplication object to resolve focus problems
- 07/01/93 ps added tAdvMdiWindow object to solve MessageBox problem
- 07/05/93 ps added hEditBuffer to save system resources for Edit Ctls
- 07/23/93 ps added wm_EnterIdle sending to RunModal
- 08/10/93 ps fixed ListBox focus problem
- 08/28/93 ps added dm_SetDefId and dm_GetDefId handling
- 08/30/93 ps added calls to DefDialogProc() for proper default PushButton handling
- 09/02/93 ps included tJanusDialogWindow properties in tDialogWindow
- 09/11/93 ps added Ctl3D support
- 10/01/93 ps added use of DynLink to DYNAMICALLY link DLLs
- 10/15/93 ps added focus autofollow
- 12/10/93 ps added BorDlg_Gray support
- 01/01/94 ms/ps fixed Ctl-Tab bug in wmSysCommand, change wmSetFocus
- 01/01/94 ps remove all calls to DefDlgProc, do all DefDlg stuff in tDialogWindow
- 01/21/94 ps fix bug in resource parsing when menuname is an integer atom of form #$xx00
- 02/14/94 ps added support for VBX control
- 03/03/94 ps fix OWL wm_Activate bug
- 03/14/94 pl/ps make MapDialogRect compatible
-
- Contributing: Jeroen W. Pluimers (jwp)
- Dan O. Butler (dob) [72134,633]
- Andy Cook [71331,501]
- Dean Wyant [75110,3253]
- Max Stempfhuber (ms) [100140,2034]
- Per Larsen (pl) [100121,1514]
-
- Copyright (c) 1994 Peter Sawatzki. All Rights Reserved.
-
- }
- {$A+,B-,F-,G+,I-,K+,P-,Q-,R-,S-,T-,V-,X+}
- Interface
- Uses
- DynLink,
- Vbx,
- WinTypes,
- Win31,
- {$IfDef Custom}
- CustomWn,
- {$EndIf}
- {$IfDef Debug}
- Debug,
- {$EndIf}
- Objects,
- oWindows;
- Const
- wm_EnterMenuLoop = $0211; {undocumented}
- MdiS_AllChildStyles = $0001;
-
- {-private message for tDialogWindow}
- wm_TrackFocus = (wm_User+3);
-
- {-style bits for DlgStyle}
- OrgStyle = $00;
- ForceStd = $01; {Force BorDlgs to appear as Std dialogs}
- ForceBor = $02; {Force Std dialogs to appear as BorDlgs}
- EnableCtl3D= $04; {Enable Ctl3D}
- ForceGrayBk= $08; {Force a gray background}
- GrayBorDlg = $10; {gray Borland dialogs}
- DefStyle: Word = OrgStyle Or EnableCtl3D Or ForceGrayBk; {use OrgStyle by default}
- DefCtl3DStyle: LongInt = Ctl3D_All;
- DefFontWeight: Integer = fw_Bold; {standard Windows behaviour}
-
- Type
- tChildClass = Record
- wX, wY, wCX, wCY: Integer;
- wID: Word;
- dwStyle: LongInt;
- szClass: Array[0..63] Of Char;
- szTitle: Array[0..131] Of Char;
- CtlDataSize: Byte;
- CtlData: Array[0..255] Of Byte;
- End;
-
- tDialogWindowAttr = Record
- Name: pChar;
- ItemCount: Integer;
- MenuName,
- ClassName,
- FontName: pChar;
- Font: hFont;
- FontWeight: Integer;
- PointSize: Integer;
- DlgItems: Pointer; {only valid ...}
- VbInfo: Pointer; {... during Create}
- ResW, {dialogs initial width ...}
- ResH: Integer; {... and height}
- wUnitsX,
- wUnitsY: Word;
- hEditBuffer: tHandle;
- End;
-
- {$IfDef Custom}
- Ancestor = tCustomWindow;
- {$Else}
- Ancestor = tWindow;
- {$EndIf}
- pDialogWindow = ^tDialogWindow;
- tDialogWindow = Object(Ancestor)
- DialogAttr: tDialogWindowAttr;
- ModalCode: pInteger;
-
- DlgStyle: Word;
- Ctl3DStyle: LongInt;
- DefId: hWnd;
- IsBorDlg: Boolean;
- Constructor Init (aParent: pWindowsObject; aName: pChar);
- Constructor InitCustom (aParent: pWindowsObject; aName: pChar; aDlgStyle: Word);
- Destructor Done; Virtual;
- Procedure AllocateEditBuffer; Virtual;
- Function Create: Boolean; Virtual;
- Procedure Destroy; Virtual;
- Procedure SetupWindow; Virtual;
- Function GetClassName: pChar; Virtual;
- Procedure GetWindowClass (Var aWndClass: tWndClass); Virtual;
- Procedure GetChildClass (Var aChildClass: tChildClass); Virtual;
- Procedure MangleChildClass (Var aChildClass: tChildClass); Virtual;
- Function CreateDialogChild ({Bp7.01: Const} Var aChildClass: tChildClass): hWnd; Virtual;
- Function CreateDialogChildren: Boolean; Virtual;
- Procedure CreateDialogFont;
- Procedure GetDialogInfo (aPtr: Pointer);
- Procedure StoreDMInfo;
- Procedure UpdateDialog; Virtual;
- Procedure MangleClass; Virtual;
- Procedure SetWindowProcs; Virtual;
- Function RunModal: Integer; Virtual;
- Function IsModal: Boolean;
- Procedure EndDlg (aRetValue: Integer); Virtual;
- Function GetItemHandle (DlgItemID: Integer): hWnd;
- Function SendDlgItemMsg (DlgItemID: Integer; aMsg, wParam: Word; lParam: LongInt): LongInt;
- Procedure Ok (Var Msg: tMessage); Virtual id_First+id_Ok;
- Procedure Cancel (Var Msg: tMessage); Virtual id_First+id_Cancel;
- Procedure wmClose (Var Msg: tMessage); Virtual wm_First+wm_Close;
- Procedure wmQueryEndSession (Var Msg: tMessage); Virtual wm_First+wm_QueryEndSession;
- Procedure wmSize (Var Msg: tMessage); Virtual wm_First+wm_Size;
- Procedure wmLButtonDown (Var Msg: tMessage); Virtual wm_First+wm_LButtonDown;
- Procedure wmNcLButtonDown (Var Msg: tMessage); Virtual wm_First+wm_NcLButtonDown;
- Procedure wmEnterMenuLoop (Var Msg: tMessage); Virtual wm_First+wm_EnterMenuLoop;
- Procedure wmActivate (Var Msg: tMessage); Virtual wm_First+wm_Activate;
- Procedure HideComboListBox;
- Procedure wmNextDlgCtl (Var Msg: tMessage); Virtual wm_First+wm_NextDlgCtl;
- Procedure dmGetDefId (Var Msg: tMessage); Virtual wm_First+dm_GetDefId;
- Procedure wmTrackFocus (Var Msg: tMessage); Virtual wm_First+wm_TrackFocus;
- Procedure wmSetFocus (Var Msg: tMessage); Virtual wm_First+wm_SetFocus;
- Procedure wmCtlColor (Var Msg: tMessage); Virtual wm_First+wm_CtlColor;
- Procedure wmPaint (Var Msg: tMessage); Virtual wm_First+wm_Paint;
- Procedure wmEraseBkGnd (Var Msg: tMessage); Virtual wm_First+wm_EraseBkGnd;
- Procedure wmVbxFireEvent (Var Msg: tMessage); Virtual wm_First+wm_VbxFireEvent;
- Procedure DefaultEventProc (Var Event: tVbxEvent); Virtual;
- End;
-
- pAdvApplication = ^tAdvApplication;
- tAdvApplication = Object(tApplication)
- Function ProcessDlgMsg (Var Message: tMsg): Boolean; Virtual;
- Function ProcessAppMsg (Var Message: tMsg): Boolean; Virtual;
- End;
-
- pAdvMdiWindow = ^tAdvMdiWindow;
- tAdvMdiWindow = Object(tMdiWindow)
- Procedure wmActivate (Var Msg: tMessage); Virtual wm_First+wm_Activate;
- End;
-
- Function ExecDialogWindow (aDialogWindow: pDialogWindow): Integer;
-
- Implementation
- Uses
- WinProcs,
- Strings;
-
- Const
- sztDialogWindow = 'tDialogWindow';
-
- ws_MdiChild = ws_Child Or ws_ClipSiblings Or ws_SysMenu Or ws_Caption Or
- ws_ThickFrame Or ws_MinimizeBox Or ws_MaximizeBox Or ws_Visible;
- ws_MdiAllowed = ws_MdiChild Or ws_Minimize Or ws_Maximize Or ws_ClipChildren Or
- ws_Disabled Or ws_HScroll Or ws_VScroll Or ws_ThickFrame Or $FFFF;
- {dialog window words}
- dwl_MsgResult = 0;
- dwl_DlgProc = 4;
- dwl_User = 8;
- dww_wUnitsX = 12;
- dww_wUnitsY = 14;
- dww_hWndFocusSave = 16;
- dww_fEnd = 18; {DM's flag for end dialog}
- dww_Result = 22; {default id and dialog result}
- dww_hData = 24; {handle to edit memory block}
- dww_hUserFont = 26; {handle to dialog font}
-
- Function DlgToClientX (x, Units: Integer): Integer;
- {DlgToClientX:= x*Units Div 4}
- Inline($59/$58/ {Pop Cx Ax}
- $F7/$E1/ {Mul Cx}
- $D1/$E8/ {Shr Ax,1}
- $D1/$E8); {Shr Ax,1}
-
- Function DlgToClientY (y, Units: Integer): Integer;
- {DlgToClientY:= y*Units Div 8}
- Inline($59/$58/ {Pop Cx Ax}
- $F7/$E1/ {Mul Cx}
- $D1/$E8/ {Shr Ax,1}
- $D1/$E8/ {Shr Ax,1}
- $D1/$E8); {Shr Ax,1}
-
- Constructor tDialogWindow.Init (aParent: pWindowsObject; aName: pChar);
- Begin
- Inherited Init(aParent,sztDialogWindow); {fake title}
- FillChar(DialogAttr,SizeOf(DialogAttr),0);
- ModalCode:= Nil; {assume modeless window}
- DlgStyle:= DefStyle; {assume default style}
- Ctl3DStyle:= DefCtl3DStyle;
- IsBorDlg:= False; {really unknown at this moment}
- DefId:= 0;
- With DialogAttr Do Begin
- hEditBuffer:= 0; {no edit buffer allocated yet}
- FontWeight:= DefFontWeight; {Windows standard dialogs are bold}
- If PtrRec(aName).Seg=0 Then Name:= aName Else Name:= StrNew(aName)
- End
- End;
-
- Constructor tDialogWindow.InitCustom (aParent: pWindowsObject; aName: pChar; aDlgStyle: Word);
- Begin
- tDialogWindow.Init (aParent, aName); {very important to use 'tDialogWindow.' !!!}
- DlgStyle:= aDlgStyle
- End;
-
- Destructor tDialogWindow.Done;
- Begin
- With DialogAttr Do Begin
- If PtrRec(Name).Seg<>0 Then StrDispose(Name);
- If PtrRec(MenuName).Seg<>0 Then StrDispose(MenuName);
- StrDispose(ClassName);
- StrDispose(FontName)
- End;
- Inherited Done
- End;
-
- Procedure tDialogWindow.AllocateEditBuffer;
- {-allocate a local heap for edit controls}
- Begin
- DialogAttr.hEditBuffer:= GlobalAlloc(GHnd, 4096)
- End;
-
- Function tDialogWindow.Create: Boolean;
- Var
- aRes, VbRes: tHandle;
- Begin
- Create:= False;
- If (Status<>0) Or (DialogAttr.Name=Nil) Then
- Exit;
- aRes:= FindResource(hInstance, DialogAttr.Name, rt_Dialog);
- If aRes<>0 Then
- aRes:= LoadResource(hInstance, aRes);
- If aRes=0 Then
- Status:= em_InvalidWindow
- Else Begin
- If Assigned(ModalCode) Then Begin
- If Assigned(Parent) Then
- EnableWindow(Parent^.hWindow, False); {disable Parent}
- ModalCode^:= 0 {begin modal state}
- End;
- VbRes:= FindResource(hInstance, DialogAttr.Name, rt_DlgInit);
- If VbRes<>0 Then Begin
- VbRes:= LoadResource(hInstance, VbRes);
- DialogAttr.VbInfo:= LockResource(VbRes)
- End;
- GetDialogInfo(LockResource(aRes));
- If Assigned(DialogAttr.MenuName) Then
- Attr.Menu:= LoadMenu(hInstance, DialogAttr.MenuName);
- CreateDialogFont;
- UpdateDialog;
- MangleClass;
- SetWindowProcs;
- EnableKBHandler;
- Create:= Inherited Create;
- UnlockResource(aRes);
- FreeResource(aRes);
- If VbRes<>0 Then Begin
- UnlockResource(VbRes);
- FreeResource(VbRes)
- End
- End
- End;
-
- Procedure tDialogWindow.Destroy;
- Begin
- If Assigned(ModalCode) Then Begin
- If Assigned(Parent) Then
- EnableWindow(Parent^.hWindow,True); {enable Parent}
- If ModalCode^=0 Then {terminate modal window if not already terminated}
- ModalCode^:= id_Cancel
- End;
-
- Inherited Destroy;
- With DialogAttr Do Begin
- If Assigned(FontName) Then
- DeleteObject(Font);
- If hEditBuffer<>0 Then
- hEditBuffer:= GlobalFree(hEditBuffer)
- End;
- End;
-
- Procedure tDialogWindow.SetupWindow;
- Begin
- StoreDMInfo;
- SendMessage(hWindow,wm_SetFont,DialogAttr.Font,0);
- If Not CreateDialogChildren Then
- Status:= em_InvalidChild;
- Inherited SetupWindow
- End;
-
- Procedure tDialogWindow.wmPaint(Var Msg: tMessage);
- Var
- PaintInfo: tPaintStruct;
- aRect: tRect;
- Begin
- PaintInfo.hDC:= GetDC(hWindow); {BeginPaint does not do the job}
- GetClientRect(hWindow, PaintInfo.rcPaint);
- If Assigned(Scroller) Then Scroller^.BeginView(PaintInfo.hDC, PaintInfo);
- Paint(PaintInfo.hDC, PaintInfo);
- If Assigned(Scroller) Then Scroller^.EndView;
- ReleaseDC(hWindow, PaintInfo.hDC);
- DefWndProc(Msg)
- End;
-
- Function tDialogWindow.GetClassName: pChar;
- Begin
- If Assigned(DialogAttr.ClassName) Then
- GetClassName:= DialogAttr.ClassName
- Else
- GetClassName:= wc_Dialog
- End;
-
- Procedure tDialogWindow.GetWindowClass (Var aWndClass: tWndClass);
- Begin
- Inherited GetWindowClass(aWndClass);
- aWndClass.cbWndExtra:= DlgWindowExtra
- End;
-
- Procedure tDialogWindow.GetChildClass (Var aChildClass: tChildClass);
- {-change a childs window class. Standard windows behaviour is simulated here:
- change special resource shortcuts (#$80..#$85) to their appropriate class names}
- Const
- PreDefClasses: Array[#$80..#$85] Of pChar =
- ('Button','Edit','Static','ListBox','ScrollBar','ComboBox');
- Begin
- MangleChildClass(aChildClass);
- With aChildClass Do
- Case szClass[0] Of
- #$80..#$85: StrCopy(szClass,PreDefClasses[szClass[0]])
- End
- End;
-
- Procedure tDialogWindow.MangleChildClass (Var aChildClass: tChildClass);
- Begin With aChildClass Do Begin
- If DlgStyle And ForceBor<>0 Then Begin
- If szClass[0]=#$80 Then
- Case dwStyle And $F Of
- bs_CheckBox,
- bs_AutoCheckBox: StrCopy(szClass,BorCheck);
- bs_RadioButton..bs_Auto3State,
- bs_AutoRadioButton: StrCopy(szClass,BorRadio);
- bs_GroupBox: StrCopy(szClass,BorShade);
- End
- End Else
- If DlgStyle And ForceStd<>0 Then Begin
- If (StrIComp(szClass,BorCheck)=0)
- Or (StrIComp(szClass,BorRadio)=0)
- Or (StrIComp(szClass,BorButton)=0) Then szClass[0]:= #$80
- Else If (StrIComp(szClass,BorShade)=0) Then
- Case dwStyle And $F Of
- bss_Group: Begin szClass[0]:= #$80; dwStyle:= (dwStyle And $FFFF0FF0) Or bs_GroupBox End;
- bss_Hdip,
- bss_Hbump,
- bss_Vdip,
- bss_Vbump: Begin szClass[0]:= #$82; dwStyle:= (dwStyle And $FFFFFFF0) Or ss_BlackRect End;
- End
- End
- End End;
-
- Function tDialogWindow.CreateDialogChild ({Bp7.01: Const} Var aChildClass: tChildClass): hWnd;
- Var
- aCtl: hWnd;
- lpDlgItemInfo: Pointer;
- Inst: tHandle;
- Begin
- With DialogAttr, aChildClass Do Begin
- If CtlDataSize=0 Then
- lpDlgItemInfo:= Nil
- Else
- lpDlgItemInfo:= @CtlData;
-
- Inst:= System.hInstance;
- If (Attr.Style And ds_LocalEdit=0) And (StrIComp(szClass, 'Edit')=0) Then Begin
- If hEditBuffer=0 Then
- AllocateEditBuffer;
- If hEditBuffer<>0 Then
- Inst:= hEditBuffer
- End;
-
- If StrIComp(szClass,'VBControl')=0 Then
- aCtl:= dVbx.CreateControl(hWindow, wId, szTitle, dwStyle,
- DlgToClientX(wX,wUnitsX), DlgToClientY(wY,wUnitsY),
- DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
- VbInfo)
- Else Begin
- aCtl:= CreateWindowEx(ws_Ex_NoParentNotify, szClass, szTitle, dwStyle,
- DlgToClientX(wX,wUnitsX), DlgToClientY(wY,wUnitsY),
- DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
- hWindow, wID, Inst,
- lpDlgItemInfo);
- If aCtl<>0 Then Begin
- If Inst=hEditBuffer Then
- SendMessage(aCtl, em_LimitText, 0, 0);
- SendMessage(aCtl, wm_SetFont, Font, 0)
- End
- End;
- {$IfDef Debug}
- If (aCtl=0) Or Not IsWindow(aCtl) Then
- WriteLn('err DialogWn: CreateDialogChild failed! Class= ',
- StrPasEx(szClass),' Title=', StrPasEx(szTitle));
- {$EndIf}
- CreateDialogChild:= aCtl
- End
- End;
-
- Function tDialogWindow.CreateDialogChildren: Boolean;
- Var
- i: Integer;
- aPtr: pChar;
- anItem: tChildClass;
- aCtl: hWnd;
- Begin
- CreateDialogChildren:= False;
- aPtr:= DialogAttr.DlgItems;
- With DialogAttr, anItem Do
- For i:= 1 To DialogAttr.ItemCount Do Begin
- {-copy fixed header and first byte of szClass}
- Move(aPtr^,anItem,15); Inc(Word(aPtr),15);
- Case szClass[0] Of
- #$80..#$85: szClass[1]:= #0; {be safe}
- Else
- StrCopy(szClass+1, aPtr); {copy rest of classname}
- Inc(Word(aPtr),StrLen(aPtr)+1)
- End;
- If aPtr^=#255 Then Begin {fiddle with Caption as a number}
- Str(pWord(aPtr+1)^, szTitle); {convert to '#xxx' form}
- Move(szTitle[0], szTitle[1], StrLen(szTitle)+1);
- szTitle[0]:= '#';
- Inc(Word(aPtr), SizeOf(Byte)+SizeOf(Word))
- End Else Begin
- StrCopy(szTitle,aPtr);
- Inc(Word(aPtr),StrLen(aPtr)+1)
- End;
- Move(aPtr^,CtlDataSize,Byte(aPtr^)+1);
- Inc(Word(aPtr),CtlDataSize+1);
- {-give descendants a chance to change child class}
- GetChildClass(anItem);
- aCtl:= CreateDialogChild(anItem);
- If aCtl<>0 Then Begin
- If (dwStyle And ws_TabStop<>0) And (FocusChildHandle=0) Then
- FocusChildHandle:= aCtl; {set focus to first tab ctl}
- If (dwStyle And bs_DefPushButton<>0)
- And (SendMessage(aCtl, wm_GetDlgCode, 0, 0) And DlgC_DefPushButton<>0) Then
- DefId:= wId
- End
- End;
-
- {-subclass the dialog for Ctl3D}
- If DlgStyle And EnableCtl3D<>0 Then
- dCtl3D.SubClassDlgEx(hWindow, Ctl3DStyle);
-
- If (DefId=0) And (GetDlgItem(hWindow, 1)<>0) Then
- DefId:= 1; {Windows forces the Ok button to be the default button}
- If DefId<>0 Then
- SendMessage(GetDlgItem(hWindow, DefId), bm_SetStyle, bs_DefPushButton, 0); {so let the buttons style reflect this}
- DialogAttr.DlgItems:= Nil; {no longer valid}
- CreateDialogChildren:= True
- End;
-
- Procedure tDialogWindow.GetDialogInfo (aPtr: Pointer);
- Begin
- With Attr,DialogAttr Do Begin
- Style:= LongInt(aPtr^); Inc(Word(aPtr),SizeOf(LongInt));
- ItemCount:= Byte(aPtr^); Inc(Word(aPtr),SizeOf(Byte));
- If Not IsFlagSet(wb_MdiChild) Then
- X:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
- Y:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
- W:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
- H:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
- If Byte(aPtr^)=255 Then Begin
- MenuName:= pChar(pWord(pChar(aPtr)+1)^); {<g>}
- Inc(Word(aPtr), SizeOf(Byte)+SizeOf(Word))
- End Else Begin
- MenuName:= StrNew(aPtr);Inc(Word(aPtr),StrLen(aPtr)+1)
- End;
- ClassName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1);
- Title:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1);
- If Style And ds_SetFont>0 Then Begin
- PointSize:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
- FontName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1)
- End Else Begin
- PointSize:= 0;
- FontName:= Nil
- End;
- If Style And ds_ModalFrame>0 Then
- ExStyle:= ExStyle Or ws_Ex_DlgModalFrame;
- DlgItems:= aPtr
- End
- End;
-
- Procedure tDialogWindow.StoreDMInfo;
- {store information in window extra words to be dialog manager compatible}
- Begin
- SetWindowLong(hWindow, dwl_DlgProc, GetWindowLong(hWindow, gwl_WndProc)); {CTL3D compatible}
- SetWindowWord(hWindow, dww_wUnitsX, DialogAttr.wUnitsX); {satisfy MapDialogRect}
- SetWindowWord(hWindow, dww_wUnitsY, DialogAttr.wUnitsY); {satisfy MapDialogRect}
- End;
-
- Procedure tDialogWindow.UpdateDialog;
- {-update and resize dialog window according to its style}
- Var
- TheMDIClient: pMdiClient;
- aRect: tRect;
- Begin With Attr, DialogAttr Do Begin
- {-update style bits for MDI}
- If isFlagSet(wb_MdiChild) Then Begin
- TheMDIClient:= Parent^.GetClient;
- {-check if the Client window has the MdiS_AllChildStyles bit set}
- If (TheMDIClient=Nil)
- Or (GetWindowLong(TheMDIClient^.hWindow, gwl_Style) And MdiS_AllChildStyles=0) Then
- Style:= ws_MdiChild
- Else
- Style:= Style And ws_MdiAllowed Or ws_Child {reject disallowed styles}
- End Else
- If Style And (ws_PopUp+ws_ThickFrame)=ws_PopUp+ws_ThickFrame Then
- ExStyle:= ExStyle And Not ws_Ex_DlgModalFrame; {correct Windows bug}
- {-reject invisible modal window}
- If Assigned(ModalCode) Then
- Attr.Style:= Attr.Style Or ws_Visible;
-
- {-resize the window according to its style and size}
- SetRect(aRect, 0, 0, DlgToClientX(w, wUnitsX), DlgToClientY(h, wUnitsY));
- AdjustWindowRectEx(aRect, Style, Menu<>0, ExStyle);
- w:= aRect.right-aRect.left;
- h:= aRect.bottom-aRect.top;
- ResW:= w;
- ResH:= h
- End End;
-
- Procedure tDialogWindow.MangleClass;
- Var
- szClass: Array[0..63] Of Char;
- ClassIsBorDlg: Boolean;
- Begin
- {-if we can't find Ctl3D, disable it's usage}
- If (DlgStyle And EnableCtl3D<>0) And Not dCtl3D.LibLink Then
- DlgStyle:= DlgStyle And Not EnableCtl3D;
- ClassIsBorDlg:= Assigned(DialogAttr.ClassName) And
- (StrLIComp(DialogAttr.ClassName, BorDialog, Length(BorDialog))=0);
- If ClassIsBorDlg And (StrLIComp(DialogAttr.ClassName, BorDialogGray, Length(BorDialogGray))=0) Then
- DlgStyle:= DlgStyle Or GrayBorDlg;
-
- {-load BWCC if the dialog needs to be a BorDlg}
- If ClassIsBorDlg Or (DlgStyle And ForceBor<>0) Then
- If Not dBWCC.LibLink Then {force std dialogs if BWCC can not be loaded}
- DlgStyle:= DlgStyle Or ForceStd And Not ForceBor;
- If DlgStyle And (ForceStd Or ForceBor)<>0 Then With DialogAttr Do Begin
- If DlgStyle And ForceBor<>0 Then
- StrCopy(szClass, BorDialog)
- Else
- szClass[0]:= #0;
- If ClassIsBorDlg Then
- StrCat(szClass, ClassName+Length(BorDialog))
- Else
- StrCat(szClass, ClassName);
-
- StrDispose(ClassName);
- ClassName:= StrNew(szClass)
- End;
- IsBorDlg:= Assigned(DialogAttr.ClassName) And (StrLIComp(DialogAttr.ClassName, BorDialog, Length(BorDialog))=0)
- End;
-
- Procedure tDialogWindow.SetWindowProcs;
- Begin
- If IsBorDlg Then Begin
- {-Class is of type BorDlg}
- If IsFlagSet(wb_MDIChild) Then
- DefaultProc:= @dBWCC.DefMdiChildProc
- Else
- DefaultProc:= @dBWCC.DefWindowProc;
- End Else Begin
- If IsFlagSet(wb_MDIChild) Then
- DefaultProc:= @DefMdiChildProc
- Else
- DefaultProc:= @DefWindowProc;
- End
- End;
-
- Procedure tDialogWindow.CreateDialogFont;
- {-create the dialog font and calculate dialog units based on font}
- Const
- aWidthString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
- Var
- aDC: hDC;
- anOldFont: hFont;
- aLogFont: tLogFont;
- aTextMetric: tTextMetric;
- Begin With DialogAttr Do Begin
- aDC:= GetDC(0);
- If FontName=Nil Then
- Font:= GetStockObject(System_Font)
- Else Begin
- FillChar(aLogFont,SizeOf(aLogFont),0);
- With aLogFont Do Begin
- StrCopy(lfFaceName,FontName);
- lfHeight:= -MulDiv(DialogAttr.PointSize,GetDeviceCaps(aDC, LogPixelsY),72);
- lfWeight:= FontWeight
- End;
- Font:= CreateFontIndirect(aLogFont)
- End;
- anOldFont:= SelectObject(aDC, Font);
- GetTextMetrics(aDC, aTextMetric);
- {-use the Microsoft recommended method to retrieve average width}
- wUnitsX:= (Word(GetTextExtent(aDC, aWidthString, Length(aWidthString)))
- Div (Length(aWidthString) Div 2) + 1) Div 2;
- wUnitsY:= aTextMetric.tmHeight;
- SelectObject(aDC, anOldFont);
- ReleaseDC(0, aDC)
- End End;
-
- Function tDialogWindow.RunModal: Integer;
- Var
- aMsg: tMsg;
- ReturnCode: Integer;
- IdleParent: tHandle;
- Begin
- ReturnCode:= 0;
- ModalCode:= @ReturnCode; {Trick OWL}
- SetFlags(wb_MDIChild, False);
- Create;
-
- If Status<>0 Then Begin
- RunModal:= Status;
- Exit
- End;
-
- If Attr.Style And ds_SysModal>0 Then
- SetSysModalWindow(hWindow); {support SysModal dialogs as well}
- If Attr.Style And ds_NoIdleMsg>0 Then
- IdleParent:= 0
- Else
- IdleParent:= GetParent(hWindow);
- Repeat
- If PeekMessage(aMsg, 0, 0, 0, pm_Remove) Then Begin
- If IdleParent<>0 Then
- SendMessage(IdleParent, wm_EnterIdle, MsgF_DialogBox, hWindow);
- If Not Application^.ProcessDlgMsg(aMsg) Then Begin
- TranslateMessage(aMsg);
- DispatchMessage(aMsg)
- End
- End
- Until ReturnCode<>0; {until window is no longer modal}
- CloseWindow;
- RunModal:= ReturnCode
- End;
-
- Function tDialogWindow.IsModal: Boolean;
- Begin
- IsModal:= Assigned(ModalCode)
- End;
-
- Procedure tDialogWindow.EndDlg (aRetValue: Integer);
- Begin
- If Assigned(ModalCode) Then {set return code if it's a modal window}
- ModalCode^:= aRetValue
- Else
- CloseWindow
- End;
-
- Function tDialogWindow.GetItemHandle (DlgItemID: Integer): hWnd;
- Begin
- GetItemHandle:= GetDlgItem(hWindow, DlgItemID)
- End;
-
- Function tDialogWindow.SendDlgItemMsg (DlgItemID: Integer; aMsg, wParam: Word; lParam: LongInt): LongInt;
- Begin
- SendDlgItemMsg:= SendDlgItemMessage(hWindow, DlgItemID, AMsg, WParam, LParam)
- End;
-
- Procedure tDialogWindow.Ok (Var Msg: tMessage);
- Begin
- If Not Assigned(ModalCode) Then
- CloseWindow
- Else
- If CanClose Then Begin
- TransferData(tf_GetData);
- EndDlg(id_Ok)
- End
- End;
-
- Procedure tDialogWindow.Cancel (Var Msg: tMessage);
- Begin
- EndDlg(id_Cancel)
- End;
-
- Procedure tDialogWindow.wmClose (Var Msg: tMessage);
- Begin
- EndDlg(id_Cancel)
- End;
-
- Procedure tDialogWindow.wmQueryEndSession (Var Msg: tMessage);
- Begin
- If Assigned(ModalCode) Then
- If @Self=Application^.MainWindow Then
- Msg.Result:= Integer(Not Application^.CanClose)
- Else
- Msg.Result:= Integer(Not CanClose)
- Else
- Inherited wmQueryEndSession(Msg)
- End;
-
- Procedure tDialogWindow.wmSize (Var Msg: tMessage);
- Begin
- Inherited wmSize(Msg);
- If Assigned(Scroller) Then With Scroller^ Do Begin
- AutoOrg:= Msg.wParam<>sizeIconic;
- If AutoOrg Then Begin
- With DialogAttr, Attr Do
- SetRange(ResW-W, ResH-H);
- ScrollTo(0, 0);
- InvalidateRect(hWindow, Nil, True)
- End
- End
- End;
-
- Procedure tDialogWindow.wmLButtonDown (Var Msg: tMessage);
- Begin
- HideComboListBox;
- Inherited wmLButtonDown(Msg)
- End;
-
- Procedure tDialogWindow.wmNcLButtonDown (Var Msg: tMessage);
- Begin
- HideComboListBox;
- {$IfDef Custom} Inherited wmNcLButtonDown(Msg) {$Else} DefWndProc(Msg) {$EndIf}
- End;
-
- Procedure tDialogWindow.wmEnterMenuLoop (Var Msg: tMessage);
- Begin
- HideComboListBox;
- DefWndProc(Msg)
- End;
-
- Procedure tDialogWindow.wmActivate (Var Msg: tMessage);
- Begin
- Inherited wmActivate(Msg);
- If Msg.wParam<>0 Then
- InvalidateRect(hWindow, Nil, True);
-
- {-this fixes an OWL bug when the last MDI child is closed}
- If (Msg.wParam=0) And (Application^.kbHandlerWnd=@Self) Then
- Application^.SetKBHandler(Nil)
- End;
-
- Procedure tDialogWindow.HideComboListBox;
- Begin
- SendMessage(FocusChildHandle, cb_ShowDropDown, 0, 0);
- End;
-
- Procedure tDialogWindow.wmNextDlgCtl (Var Msg: tMessage);
- Var
- OldFocus, NewFocus: hWnd;
- Begin
- OldFocus:= FocusChildHandle;
- If Msg.lParamLo=0 Then Begin
- If OldFocus=0 Then Begin
- {-set focus to the first tab item}
- NewFocus:= 0;
- OldFocus:= hWindow
- End Else
- If IsChild(hWindow, OldFocus) Then
- NewFocus:= GetNextDlgTabItem(hWindow, OldFocus, WordBool(Msg.wParam))
- Else
- Exit {ignore message if current focus is not a dialog ctl}
- End Else Begin
- If OldFocus=0 Then
- OldFocus:= hWindow;
- NewFocus:= Msg.wParam
- End;
- FocusChildHandle:= NewFocus;
- FocusChild;
- Msg.Result:= 0
- End;
-
- Procedure tDialogWindow.dmGetDefId (Var Msg: tMessage);
- Begin
- If DefId=0 Then
- Msg.Result:= 0
- Else Begin
- Msg.ResultLo:= DefId;
- Msg.ResultHi:= dc_HasDefId
- End
- End;
-
- Procedure tDialogWindow.wmSetFocus (Var Msg: tMessage);
- Begin
- If IsFlagSet(wb_KBHandler) And Not IsIconic(hWindow) Then Begin
- Application^.SetKBHandler(@Self);
- FocusChild;
- End Else
- Application^.SetKBHandler(Nil);
- Msg.Result:= 0
- End;
-
- Procedure tDialogWindow.wmCtlColor (Var Msg: tMessage);
- Begin
- If DlgStyle And EnableCtl3D<>0 Then With Msg Do Begin
- Result:= dCtl3D.CtlColorEx(Message, wParam, lParam);
- If Result<>0 Then
- Exit
- End;
- DefWndProc(Msg)
- End;
-
- Procedure tDialogWindow.wmEraseBkGnd (Var Msg: tMessage);
- Var
- aBrush,
- OldBrush: hBrush;
- aRect: tRect;
- Begin
- aBrush:= 0;
- If Not IsBorDlg And (DlgStyle And EnableCtl3D<>0) Then
- With Msg Do
- aBrush:= dCtl3D.CtlColorEx(CtlColor_Dlg, wParam, MakeLong(0, CtlColor_Dlg));
- If DlgStyle And (ForceGrayBk Or GrayBorDlg)<>0 Then
- aBrush:= GetStockObject(LtGray_Brush);
- If aBrush<>0 Then Begin
- UnrealizeObject(aBrush);
- OldBrush:= SelectObject(Msg.wParam, aBrush);
- GetClientRect(hWindow, aRect);
- With aRect Do PatBlt(Msg.wParam, left, top, right-left, bottom-top, PatCopy);
- SelectObject(Msg.wParam, OldBrush);
- Msg.Result:= 1
- End Else
- DefWndProc(Msg)
- End;
-
- Procedure tDialogWindow.wmTrackFocus (Var Msg: tMessage);
- Var
- aRect,
- ClientRect: tRect;
- dX, dY: Integer;
- Begin
- FocusChildHandle:= Msg.wParam;
- If Not IsIconic(hWindow) And Assigned(Scroller) And Scroller^.AutoMode Then Begin
- GetWindowRect(FocusChildHandle, aRect);
- GetClientRect(hWindow, ClientRect);
- MapWindowPoints(0, hWindow, aRect, 2); {Screen->hWindow}
- With aRect, Scroller^ Do {test if control is outside the client area}
- If (left<0) Or (right>ClientRect.right)
- Or (top<0) Or (bottom>ClientRect.bottom) Then Begin
- {-try to center the control in the client area}
- dX:= (ClientRect.right-(right-left)) Div 2; If dX<0 Then dX:= 0;
- dY:= (ClientRect.bottom-(bottom-top)) Div 2; If dY<0 Then dY:= 0;
- ScrollTo((left-dX+XPos*XUnit) Div XUnit, (top-dY+YPos*YUnit) Div YUnit)
- End
- End
- End;
-
- Procedure tDialogWindow.wmVbxFireEvent (Var Msg: tMessage);
- Begin
- If Not EventPerform(@Self, pVbxEvent(Msg.lParam)^, id_First+pVbxEvent(Msg.lParam)^.Id) Then
- DefaultEventProc(pVbxEvent(Msg.lParam)^);
- Msg.Result:= 0
- End;
-
- Procedure tDialogWindow.DefaultEventProc (Var Event: tVbxEvent);
- Begin
- With Event Do If GetObjectPtr(Window)<>Nil Then {route to object}
- SendMessage(Window, wm_VbxFireEvent, 0, LongInt(@Event))
- End;
-
- Function ExecDialogWindow (aDialogWindow: pDialogWindow): Integer;
- Var
- ExecReturn: Integer;
- Begin
- ExecDialogWindow:= id_Cancel;
- If Application^.ValidWindow(aDialogWindow)<>Nil Then Begin
- ExecReturn:= aDialogWindow^.RunModal;
- If ExecReturn<0 Then
- Application^.Error(ExecReturn)
- Else
- ExecDialogWindow:= ExecReturn
- End
- End;
-
- Function tAdvApplication.ProcessDlgMsg (Var Message: tMsg): Boolean;
- Var
- hKbdWnd,
- hFocus: tHandle;
- Begin
- ProcessDlgMsg:= False;
-
- If KBHandlerWnd=Nil Then Exit;
- hKbdWnd:= KBHandlerWnd^.hWindow;
- If hKbdWnd=0 Then Exit;
-
- If Not IsDialogMessage(hKbdWnd, Message) Then Exit;
-
- ProcessDlgMsg:= True;
- If IsWindow(hKbdWnd) And Not IsIconic(hKbdWnd) Then Begin
- hFocus:= GetFocus;
-
- If IsChild(hKbdWnd, hFocus)
- And (pWindow(KBHandlerWnd)^.FocusChildHandle<>hFocus) Then
- SendMessage(hKbdWnd, wm_TrackFocus, hFocus, 0)
- End
- End;
-
- Function tAdvApplication.ProcessAppMsg (Var Message: tMsg): Boolean;
- Const
- MdiTest: (NotTested, IsMdi, IsNotMdi) = NotTested;
- Begin
- If (MdiTest=NotTested) And Assigned(MainWindow) Then
- If MainWindow^.GetClient=Nil Then
- MdiTest:= IsNotMdi
- Else
- MdiTest:= IsMdi;
- If MdiTest=IsMdi Then
- ProcessAppMsg:= ProcessMDIAccels(Message)
- Or ProcessAccels(Message)
- Or ProcessDlgMsg(Message)
- Else
- ProcessAppMsg:= ProcessDlgMsg(Message)
- Or ProcessMDIAccels(Message)
- Or ProcessAccels(Message)
- End;
-
- Procedure tAdvMdiWindow.wmActivate (Var Msg: tMessage);
- Var
- TopWnd: hWnd;
- Begin
- Inherited wmActivate(Msg);
- If (Msg.wParam<>0) And Assigned(ClientWnd) Then Begin
- TopWnd:= LoWord(SendMessage(ClientWnd^.hWindow, wm_MdiGetActive, 0, 0));
- If TopWnd<>0 Then
- SendMessage(TopWnd, wm_Activate, wa_Active, 0)
- End
- End;
-
- End.
-