home *** CD-ROM | disk | FTP | other *** search
- Unit DialogWn;
- { Unit: DialogWn
- Version: 1.01
- Purpose: make a descendant of tWindow named tDialogWindow that behaves like
- a modeless dialog.
- Features: - tDialogWindow descends from tWindow
- - tDialogWindow and descendants may be used as MDI childs
- - support for calculated resources is included e.g. a dialog
- childs class & style may be changed on-the-fly (see GetChildClass)
- tJanusDialogWindow object is an example for this: it decides at
- runtime whether to uses BorDlg's or standard dialogs
- Date: 26.07.1992
-
- Developer: Peter Sawatzki (PS)
- Buchenhof 3, D-5800 Hagen 1, Germany
- CompuServe: 100031,3002
- FIDO: 2:245/5800.17
- BITNET: IN307@DHAFEU11
-
- Copyright (c) 1992 Peter Sawatzki. All Rights Reserved.
-
- Contributing: Jeroen W. Pluimers (jwp)
- CompuServe: 100013,1443
- Internet: jeroenp@rulfc1.leidenuniv.nl
- Fidonet: 2:281/521
-
- History: 22.04.92 - intial release by PS
- 26.07.92 - added Scroller support by PS and jwp
-
- }
- Interface
- Uses
- WinTypes,
- WObjects;
- Type
- tChildClass = Record
- wX, wY, wCX, wCY, wID: Integer;
- 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;
- PointSize: Integer;
- DlgItems: Pointer;
- ResW,
- ResH: Integer;
- wUnitsX,
- wUnitsY: Word
- End;
-
- pDialogWindow = ^tDialogWindow;
- tDialogWindow = Object(tWindow)
- DialogAttr: tDialogWindowAttr;
- Constructor Init (aParent: pWindowsObject; aName: pChar);
- Destructor Done; Virtual;
- Function Create: Boolean; Virtual;
- Procedure Destroy; Virtual;
- Procedure SetupWindow; Virtual;
- Function GetClassName: pChar; Virtual;
- Function NewClassName: pChar; Virtual;
- Procedure SetClassName; Virtual;
- Procedure GetChildClass (Var aChildClass: tChildClass); Virtual;
- Function CreateDialogChild (Var aChildClass: tChildClass): hWnd; Virtual;
- Procedure CreateDialogChildren;
- Procedure CreateDialogFont;
- Procedure GetDialogInfo (aPtr: Pointer);
- Procedure UpdateDialog;
- Procedure Ok (Var Msg: tMessage); Virtual id_First+id_Ok;
- Procedure Cancel (Var Msg: tMessage); Virtual id_First+id_Cancel;
- Procedure wmMDIActivate (Var Msg: tMessage); Virtual wm_First+wm_MDIActivate;
- (*Procedure wmNCActivate (Var Msg: tMessage); Virtual wm_First+$46;*)
- procedure WMSize(var Msg: TMessage); virtual wm_First + wm_Size;
- End;
-
- Implementation
- Uses
- WinProcs,
- Strings;
- Const
- sztDialogWindow = 'tDialogWindow';
-
- 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
- tWindow.Init(aParent,sztDialogWindow); {fake title}
- FillChar(DialogAttr,SizeOf(DialogAttr),0);
- With DialogAttr Do
- If PtrRec(aName).Seg=0 Then Name:= aName Else Name:= StrNew(aName)
- End;
-
- Destructor tDialogWindow.Done;
- Begin
- With DialogAttr Do Begin
- If PtrRec(Name).Seg<>0 Then StrDispose(Name);
- StrDispose(MenuName);
- StrDispose(ClassName);
- If FontName<>Nil Then
- StrDispose(FontName)
- End;
- tWindow.Done
- End;
-
- Function tDialogWindow.Create: Boolean;
- Var
- aRes: tHandle;
- Begin
- EnableKBHandler;
- If DialogAttr.Name=Nil Then
- Exit;
- aRes:= LoadResource(hInstance,
- FindResource(hInstance, DialogAttr.Name, rt_Dialog));
- If aRes=0 Then
- Status:= em_InvalidWindow
- Else Begin
- GetDialogInfo(LockResource(aRes));
- SetClassName; {let descendants change the class name}
- CreateDialogFont;
- UpdateDialog;
- Create:= tWindow.Create;
- UnlockResource(aRes);
- FreeResource(aRes)
- End
- End;
-
- Procedure tDialogWindow.Destroy;
- Begin
- If DialogAttr.FontName<>Nil Then
- DeleteObject(DialogAttr.Font);
- tWindow.Destroy
- End;
-
- Procedure tDialogWindow.SetupWindow;
- const
- BorDialog = 'BorDlg';
- Begin
- SendMessage(hWindow,wm_SetFont,DialogAttr.Font,0);
- CreateDialogChildren;
- tWindow.SetupWindow;
- If (Scroller<>Nil)
- And (StrLIComp(DialogAttr.ClassName,BorDialog,Length(BorDialog)) = 0) Then
- With Scroller^ Do Begin
- {fix BWCC background quirk}
- XUnit:= (XUnit + 1) And Not 1; { make even }
- YUnit:= (YUnit + 1) And Not 1
- End
- End;
-
- Function tDialogWindow.GetClassName: pChar;
- Begin
- If NewClassName=Nil Then
- If DialogAttr.ClassName=Nil Then
- GetClassName:= sztDialogWindow
- Else
- GetClassName:= DialogAttr.ClassName
- Else
- GetClassName:= NewClassName
- End;
-
- Function tDialogWindow.NewClassName: pChar;
- Begin
- {-tDialogWindow gets the Class name from the dialog resource}
- NewClassName:= Nil
- End;
-
- Procedure tDialogWindow.SetClassName;
- Begin
- If NewClassName<>Nil Then Begin
- StrDispose(DialogAttr.ClassName);
- DialogAttr.ClassName:= StrNew(NewClassName)
- End
- 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
- With aChildClass Do
- Case szClass[0] Of
- #$80..#$85: StrCopy(szClass,PreDefClasses[szClass[0]])
- End
- End;
-
- Function tDialogWindow.CreateDialogChild (Var aChildClass: tChildClass): hWnd;
- Var
- aCtl: hWnd;
- lpDlgItemInfo: Pointer;
- Begin
- With DialogAttr, aChildClass Do Begin
- If CtlDataSize=0 Then
- lpDlgItemInfo:= Nil
- Else
- lpDlgItemInfo:= @CtlData;
- aCtl:= CreateWindow(szClass, szTitle, dwStyle,
- DlgToClientX(wX,wUnitsX), DlgToClientY(wY,wUnitsY),
- DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
- hWindow, wID, System.hInstance,
- lpDlgItemInfo);
- If aCtl<>0 Then
- SendMessage(aCtl, wm_SetFont, Font, 0)
- End;
- CreateDialogChild:= aCtl
- End;
-
- Procedure tDialogWindow.CreateDialogChildren;
- Var
- i: Integer;
- sp: Pointer;
- anItem: tChildClass;
- Begin
- sp:= DialogAttr.DlgItems;
- With DialogAttr,anItem Do
- For i:= 1 To DialogAttr.ItemCount Do Begin
- {-copy fixed header and first byte of szClass}
- Move(sp^,anItem,15); Inc(Word(sp),15);
- Case szClass[0] Of
- #$80..#$85: szClass[1]:= #0; {be safe}
- Else
- StrCopy(szClass+1,sp); {copy rest of classname}
- Inc(Word(sp),StrLen(sp)+1)
- End;
- StrCopy(szTitle,sp); Inc(Word(sp),StrLen(sp)+1);
- Move(sp^,CtlDataSize,Byte(sp^)+1);
- Inc(Word(sp),CtlDataSize+1);
- {-maybe a descendant class wants to change child names :-) }
- GetChildClass(anItem);
- If CreateDialogChild(anItem)=0 Then Begin
- Status:= em_InvalidChild;
- Exit
- End
- End
- 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));
- MenuName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1);
- 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;
- DlgItems:= aPtr
- End
- 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
- {-reject use of ws_PopUp for a MDI child!}
- If Style And ws_PopUp<>0 Then
- Style:= (Style Or ws_Child) And Not ws_PopUp;
- TheMDIClient:= Parent^.GetClient;
- {-check if the Client window has the MDIs_allChildStyles bit set}
- If (TheMDIClient=Nil)
- Or (GetWindowLong(TheMDIClient^.hWindow,gwl_Style) And 1=0) Then
- Style:= Style Or ws_Child Or ws_ClipSiblings Or ws_ClipChildren
- Or ws_SysMenu Or ws_Caption Or ws_ThickFrame
- Or ws_MinimizeBox Or ws_MaximizeBox
- End;
-
- {-resize the window according to its style and size}
- With aRect Do Begin
- left:= 0;
- top:= 0;
- right:= DlgToClientX(w, wUnitsX);
- bottom:= DlgToClientY(h, wUnitsY);
- AdjustWindowRect(aRect, Style, Menu<>0);
- w:= right-left;
- h:= bottom-top;
- ResW:= w;
- ResH:= h;
- End
- 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:= FW_BOLD
- End;
- Font:= CreateFontIndirect(aLogFont)
- End;
- anOldFont:= SelectObject(aDC, Font);
- GetTextMetrics(aDC, aTextMetric);
- {-use the Microsoft recommended way to retrieve average width}
- wUnitsX:= Word(GetTextExtent(aDC, aWidthString, Length(aWidthString))) Div Length(aWidthString);
- wUnitsY:= aTextMetric.tmHeight;
- SelectObject(aDC, anOldFont);
- ReleaseDC(0, aDC)
- End End;
-
- Procedure tDialogWindow.Ok (Var Msg: tMessage);
- Begin
- CloseWindow
- End;
-
- Procedure tDialogWindow.Cancel (Var Msg: tMessage);
- Begin
- CloseWindow
- End;
-
- Procedure tDialogWindow.wmMDIActivate(Var Msg: tMessage);
- Begin
- wmActivate(Msg)
- End;
-
- (*Procedure tDialogWindow.wmNCActivate(Var Msg: tMessage);
- Begin
- {If Msg.wParam=0 Then}
- Msg.Result:= 0
- {Else
- With Msg Do Result:= DefWindowProc(Receiver, Message, wParam, lParam)
- }
- End; *)
-
- Procedure tDialogWindow.WMSize(var Msg: TMessage);
- Begin
- TWindow.WMSize(Msg);
- If Scroller <> Nil Then With Scroller^ Do Begin
- AutoOrg:= Msg.wParam <> sizeIconic;
- If Msg.WParam <> sizeIconic Then Begin
- With DialogAttr, Attr Do
- SetRange(ResW - W, ResH - H);
- ScrollTo(0, 0);
- InvalidateRect(HWindow, nil, True)
- End
- End
- End;
-
- End.
-