home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
dtx9203
/
smartico
/
tbwin.pas
< prev
Wrap
Pascal/Delphi Source File
|
1992-03-31
|
27KB
|
800 lines
(*$A+,B-,D+,F-,G+,I+,L+,N-,R+,S+,V+,W-,X+*)
(*--------------------------------------------------------*)
(* TBWIN.PAS *)
(* Copyright 1992 Mario M. Westphal & DMV-Verlag *)
(* Unit fⁿr Symbolleisten und Floating Menus *)
(* Compiler: Turbo Pascal f. Windows 1.0 *)
(*--------------------------------------------------------*)
UNIT TBWin;
INTERFACE
USES
WinTypes, WObjects, WinProcs;
(* ******* ToolBar ******* *)
CONST
MaxBreaks = 9; (* Anzahl der Trennstriche 0.. *)
TYPE
pToolBar = ^tToolBar;
tToolBar = OBJECT(tWindow)
color_TBFace : tColorRef; (* Farben *)
color_TBShadow: tColorRef;
color_TBHilite: tColorRef; (* Dialog-Basiseinheiten *)
cyDBU : INTEGER;
cxDBU : INTEGER;
bkBrush : HBrush; (* Struktur fⁿr die *)
(* Trennbalken *)
CONSTRUCTOR Init(aParent: pWindowsObject;
Height: INTEGER);
DESTRUCTOR Done; VIRTUAL;
FUNCTION GetClassName: PChar; VIRTUAL;
PROCEDURE GetWindowClass(VAR aWndClass: tWndClass);
VIRTUAL;
PROCEDURE SetColors; VIRTUAL;
PROCEDURE Paint (PaintDC: HDC;
VAR PaintInfo: tPaintStruct); VIRTUAL;
PROCEDURE SetSize;
PROCEDURE SetBarBreak(Pos: INTEGER; ShowBreak: BOOLEAN);
PRIVATE
Breaks : ARRAY[0..MaxBreaks] OF INTEGER;
BreakCnt: BYTE;
END;
(* ******* Toolbox-Windows ******* *)
CONST
MaxPanels = 20; (* Max. Anzahl Panels pro Fenster *)
SecPanelOfs = 2000; (* ID-Offset der zweiten Bitmap *)
LowResOfs = 1000; (* ID-Offs. der Bitmaps fⁿr LowRes *)
(* Status-Flags *)
tb_Null = 0; (* Keine Bitmap *)
tb_Normal = 1; (* Normal *)
tb_Selected = 2; (* Selektiert *)
tb_Toggle = 4; (* Panelzustand umschalten *)
tb_Disabled = 8; (* Panel inaktiv *)
(* Style-Flags *)
tbs_Caption = 1; (* Mit Titelleiste (=> tbs_Border) *)
tbs_Border = 2; (* Mit Rahmen *)
tbs_MultiSel = 4; (* Mehrfachauswahl erlaubt *)
tbs_MultiMsg = 8; (* Fⁿr jedes Panel eine eigene *)
(* Botschaft *)
(* Toolbox-Botschaften *)
tbm_Select = 1; (* Msg: SchaltflΣche selektiert *)
tbm_Unselect = 2; (* Msg: SchaltflΣche deselektiert *)
TYPE
(* Struktur fⁿr ein Panel (5 Bytes) *)
tPanel = RECORD
rID : WORD;
hBM : hBitmap; (* normale Bitmap *)
hBMSel : hBitmap; (* selektierte Bitmap *)
Flags : BYTE; (* Zustands-Flag *)
END;
TYPE
(* Toolbox-Objekt *)
pToolBox = ^tToolBox;
tToolBox = OBJECT(tWindow)
CONSTRUCTOR Init (aParent : pWindowsObject;
aTitle : PChar;
AID : INTEGER;
x, y, cx, cy : INTEGER;
W1, H1, W2, H2: INTEGER;
aStyle : WORD);
DESTRUCTOR Done; VIRTUAL;
FUNCTION GetClassName: PChar; VIRTUAL;
FUNCTION UseLowRes: BOOLEAN; VIRTUAL;
PROCEDURE SetTBPos(x, y: INTEGER);
PROCEDURE tbAdjust;
PROCEDURE GetTBPos(VAR r: tRect);
FUNCTION GetPanelState(id: INTEGER): INTEGER;
FUNCTION GetFocus: INTEGER;
FUNCTION SetPanelState(id: INTEGER;
aStatus: INTEGER): INTEGER;
FUNCTION SetPanel(id: INTEGER;
ResID: INTEGER) : INTEGER;
FUNCTION InsertPanel(id: INTEGER;
ResID: INTEGER) : INTEGER;
PROCEDURE DrawEmptyPanel(VAR dc: HDC;
x, y, w, h: INTEGER); VIRTUAL;
PRIVATE
pId : INTEGER;
pAs : ARRAY[0..MaxPanels-1] OF tPanel;
pACount : INTEGER;
bm_Width : INTEGER; (* Breite der Bitmap *)
bm_Height : INTEGER; (* H÷he der Bitmap *)
xClient,
yClient : INTEGER; (* Fensterbreite- und H÷he *)
InWindow : BOOLEAN; (* Maus war im TB-Client bei *)
(* LBtnDown *)
Rows,
Cols : INTEGER; (* Anzahl Zeilen und Spalten *)
tbStyle : WORD; (* Fenster-Stil *)
Focus : INTEGER; (* ID des momentan selektierten*)
(* Panels *)
MsDnID : INTEGER; (* ID des Panels bei LBtnDown *)
ActState : INTEGER; (* Zustand dieses Panels *)
PROCEDURE NotifyParent(PanelID: INTEGER; Msg: INTEGER);
PROCEDURE DrawPanel(dc: HDC; id: INTEGER;
Mode: INTEGER);
PROCEDURE Paint(PaintDC: HDC;
VAR PaintInfo: tPaintStruct); VIRTUAL;
PROCEDURE wmMove(VAR Msg: tMessage);
VIRTUAL wm_First + wm_Move;
PROCEDURE wmlButtonDown(VAR Msg: tMessage);
VIRTUAL wm_First + wm_LButtonDown;
PROCEDURE wmlButtonUp(VAR Msg: tMessage);
VIRTUAL wm_First + wm_LButtonUp;
PROCEDURE wmMouseMove(VAR Msg: tMessage);
VIRTUAL wm_First + wm_MouseMove;
END;
IMPLEMENTATION
(**********************************************************)
(* tToolbar-Symbolleiste *)
(**********************************************************)
(*------------------------------------------------------- *)
(* Erzeugt eine Symbolleiste und zeigt sie an. *)
(* aParent : Zeiger auf das Eltern-Fenster *)
(* Height : H÷he der Symbolleiste *)
CONSTRUCTOR tToolBar.Init (aParent: pWindowsObject;
Height : INTEGER);
VAR
i : INTEGER;
lDlgBU: LONGINT;
BEGIN
tWindow.Init(aParent, '');
Attr.Style := ws_Child OR ws_Visible OR ws_ClipSiblings;
Attr.x := 0;
Attr.y := 0;
Attr.w := 0;
Attr.h := Height;
(* Trenner initialisieren *)
BreakCnt := 0;
FOR i := 0 TO MaxBreaks DO Breaks[i] := 0;
(* Ermittelt die Dialog-Basiseinheiten *)
lDlgBU := GetDialogBaseUnits;
cyDBU := HiWord(lDlgBU);
cxDBU := LoWord(lDlgBU);
(* Farben festlegen *)
SetColors;
(* Pinsel fⁿr den Hintergrund der Symbolleiste *)
(* und der Kindfenster *)
bkBrush := CreateSolidBrush(color_TBFace);
END;
DESTRUCTOR tToolBar.Done;
BEGIN
tWindow.Done;
DeleteObject(bkBrush);
END;
FUNCTION tToolBar.GetClassName: PChar;
BEGIN
GetClassName := 'TOOLBAR';
END;
PROCEDURE tToolBar.GetWindowClass(VAR aWndClass: tWndClass);
(*--------------------------------------------------------*)
(* Setzt den Hintergrundpinsel und Doppelklick-Erkennung *)
BEGIN
tWindow.GetWindowClass(aWndClass);
aWndClass.Style := aWndClass.Style OR cs_DblClks;
aWndClass.hBrBackground := bkBrush;
END;
PROCEDURE tToolBar.SetColors;
(*--------------------------------------------------------*)
(* Legt die Farben fⁿr die Symbolleiste fest. *)
(* Wird bei Bedarf ⁿberschrieben. *)
VAR IC : HDC;
BEGIN
IC := CreateIC('DISPLAY', NIL, NIL, NIL);
(* Hellgrau, EGA/Herc. wei▀ *)
color_TBFace := GetNearestColor(IC, RGB(193, 193, 193));
(* Dunkelgrau, Herc. schwarz *)
color_TBShadow:= GetNearestColor(IC, RGB(85, 85, 85));
(* Immer wei▀ *)
color_TBHilite:= RGB(255, 255, 255);
DeleteDC(IC);
END;
PROCEDURE tToolBar.Paint(PaintDC: HDC;
VAR PaintInfo: tPaintStruct);
(*--------------------------------------------------------*)
(* Baut die Symbolleiste komplett neu auf *)
VAR
OPen: hPen;
Pen : hPen;
Pen2: hPen;
r : tRect;
i : INTEGER;
BEGIN
tWindow.Paint(PaintDC, PaintInfo);
GetClientRect(hWindow, r);
Pen := CreatePen(ps_Solid, 1, color_TBHilite);
Pen2 := CreatePen(ps_Solid, 1, color_TBShadow);
OPen := SelectObject(PaintDC, Pen);
MoveTo(PaintDC,0,0);
LineTo(PaintDC, r.Right + 1, 0);
SelectObject(PaintDC, Pen2);
MoveTo(PaintDC, 0, r.Bottom - 2);
LineTo(PaintDC, r.Right + 1, r.Bottom - 2);
SelectObject(PaintDC, GetStockObject(Black_Pen));
MoveTo(PaintDC, 0, r.Bottom - 1);
LineTo(PaintDC, r.Right + 1, r.Bottom - 1);
(* Trennbalken zeichnen *)
FOR i := 0 TO MaxBreaks DO
IF Breaks[i] <> 0 THEN BEGIN
SelectObject(PaintDC,Pen);
MoveTo(PaintDC,Breaks[i], 0);
LineTo(PaintDC,Breaks[i], r.Bottom - 1);
SelectObject(PaintDC, GetStockObject(Black_Pen));
MoveTo(PaintDC, Breaks[i] + 1, 0);
LineTo(PaintDC, Breaks[i] + 1, r.Bottom - 1);
END;
SelectObject(PaintDC, OPen);
DeleteObject(Pen);
DeleteObject(Pen2);
END;
PROCEDURE tToolBar.SetSize;
(*--------------------------------------------------------*)
(* Anpassen der Symbolleistenbreite. Aufruf durch die *)
(* wmSize-Methode des Eltern-Fensters! *)
VAR
r,
r2: tRect;
BEGIN
GetClientRect(Parent^.hWindow, r);
GetClientRect(hWindow, r2);
MoveWindow(hWindow, 0, 0, r.Right, r2.Bottom, TRUE);
END;
PROCEDURE tToolBar.SetBarBreak(Pos: INTEGER;
ShowBreak: BOOLEAN);
(*--------------------------------------------------------*)
(* Setzt oder l÷scht einen Trennstrich. Ist die maximale *)
(* Anzahl erreicht, wird der Aufruf ignoriert. *)
(* Pos : Horizontale Position *)
(* ShowBreak : true => setzen, sonst l÷schen *)
VAR
i: INTEGER;
BEGIN
IF ShowBreak THEN BEGIN (* Einfⁿgen *)
IF BreakCnt <= MaxBreaks THEN BEGIN
Inc(BreakCnt);
(* Freien Platz suchen *)
FOR i := 0 TO MaxBreaks DO
IF Breaks[i] = 0 THEN BEGIN
Breaks[i] := Pos;
Exit;
END;
END;
END ELSE BEGIN (* L÷schen *)
FOR i := 0 TO MaxBreaks DO
IF Breaks[i] = Pos THEN BEGIN
(* Nur den ersten gefundenen entfernen *)
Breaks[i] := 0;
Dec(BreakCnt);
Exit;
END;
END;
END;
(**********************************************************)
(* tToolBox : toolbox-Windows *)
(**********************************************************)
CONSTRUCTOR tToolBox.Init(aParent : pWindowsObject;
aTitle : PChar;
AID : INTEGER;
x, y, cx, cy : INTEGER;
W1, H1, W2, H2: INTEGER;
aStyle : WORD);
(*--------------------------------------------------------*)
(*Initialisiert ein Toolbox-Window. *)
(*AParent : Handle des Eltern-Fensters *)
(*ATitle : Fenstertitel *)
(*x, y : Obere linke Ecke des Fensters, bezⁿglich *)
(* des ⁿbergeordneten Fensters *)
(*cx, cy : Anzahl der Panels horizontal und vertikal *)
(*W1, H1 : Ma▀e der Bitmaps fⁿr HiRes *)
(*W2, H2 : Ma▀e der Bitmaps fⁿr LowRes *)
(*AStyle : Fensterstil (tbs_xxxx - Konstanten ) *)
VAR
i, COfs: INTEGER;
BEGIN
tWindow.Init(aParent, aTitle);
Cols := cx;
Rows := cy;
InWindow := FALSE;
tbStyle := aStyle;
Focus := -1;
pId := AID;
pACount := 0;
IF UseLowRes THEN BEGIN
bm_Width := W2;
bm_Height := H2;
END ELSE BEGIN
bm_Width := W1;
bm_Height := H1;
END;
FOR i := 0 TO MaxPanels - 1 DO
WITH pAs[i] DO BEGIN
hBM := 0;
hBMSel := 0;
Flags := tb_Null;
END;
(* Fenstergr÷▀e an die Bitmaps anpassen *)
Attr.x := x;
Attr.y := y;
Attr.w := cx * bm_Width;
Attr.h := cy * bm_Height;
Attr.Style := ws_Child OR ws_Visible OR
ws_ClipSiblings OR ws_Overlapped;
(* Fⁿr Fenster mit Titel wird auch ein Rahmen ben÷tigt *)
IF tbStyle AND tbs_Caption <> 0 THEN BEGIN
tbStyle := tbStyle OR tbs_Border;
Attr.Style := Attr.Style OR ws_Caption;
Inc(Attr.h, GetSystemMetrics(sm_CYCaption));
END;
(* Bei Rahmen mⁿssen Breite und H÷he angepa▀t werden *)
IF tbStyle AND tbs_Border <> 0 THEN BEGIN
Attr.Style := Attr.Style OR ws_Border;
Inc(Attr.w, 2 * GetSystemMetrics(sm_CXBorder));
Inc(Attr.h, GetSystemMetrics(sm_CYBorder));
END;
END;
DESTRUCTOR tToolBox.Done;
(*--------------------------------------------------------*)
(* Gibt den Speicher fⁿr die Bitmaps wieder frei und *)
(* schlie▀t das Fenster. *)
VAR
i: INTEGER;
BEGIN
FOR i := 0 TO MaxPanels - 1 DO BEGIN
IF pAs[i].hBMSel <> 0 THEN DeleteObject(pAs[i]. hBMSel);
IF pAs[i].hBM <> 0 THEN DeleteObject(pAs[i]. hBM);
END;
tWindow.Done;
END;
FUNCTION tToolBox.GetClassName: PChar;
BEGIN
GetClassName := 'TOOLBOX';
END;
FUNCTION tToolBox.UseLowRes: BOOLEAN;
(*--------------------------------------------------------*)
(* Liefert true, falls die Bitmaps mit der niedrigen *)
(* Aufl÷sung verwendet werden sollen. *)
BEGIN
UseLowRes := GetSystemMetrics(sm_CYScreen) < 480;
END;
PROCEDURE tToolBox.SetTBPos(x,y: INTEGER);
(*--------------------------------------------------------*)
(* Positioniert das Fenster auf die Position X, Y *)
(* bezⁿglich des ⁿbergeordneten Fensters. *)
BEGIN
IF (tbStyle AND tbs_Caption <> 0) AND
(y > GetSystemMetrics(sm_CYCaption)) THEN
Dec(y,GetSystemMetrics(sm_CYCaption));
SetWindowPos(hWindow, 0, x, y, 0, 0, swp_NoSize);
END;
PROCEDURE tToolBox.tbAdjust;
(*--------------------------------------------------------*)
(* Justiert das ToolBox-Fenster im Client-Bereich des *)
(* Eltern-Fensters. Mu▀ von der WMSize-Methode des *)
(* Eltern-Fensters aufgerufen werden. *)
VAR
rp, rc: tRect;
y : INTEGER;
BEGIN
IF IsIconic(Parent^.hWindow) THEN Exit;
GetClientRect(Parent^.hWindow, rp);
GetTBPos(rc);
IF rc.Left + 20 > rp.Right THEN BEGIN
SetTBPos(rp.Right - 20, rc.Top);
GetTBPos(rc);
END;
IF rc.Top + 20 > rp.Bottom THEN BEGIN
y := rp.Bottom - 20;
IF y < 0 THEN y := 0;
SetTBPos(rc.Left, y);
GetTBPos(rc);
END;
END;
PROCEDURE tToolBox.GetTBPos(VAR r: tRect);
(*--------------------------------------------------------*)
(* Liefert die Position und Ausdehnung des Client- *)
(* Fensters bezⁿglich des Parent-Windows. *)
VAR
tr: tRect;
BEGIN
GetClientRect(hWindow, tr);
r.Left := xClient;
r.Top := yClient;
r.Right := xClient + tr.Right;
r.Bottom := yClient + tr.Bottom;
END;
FUNCTION tToolBox.GetPanelState(id: INTEGER): INTEGER;
(*--------------------------------------------------------*)
(* Liefert den Status des Elements mit der ⁿbergebenen ID *)
(* Liefert -1, falls eine ungⁿltige ID ⁿbergeben wird. *)
BEGIN
IF (id >= 0) AND (id < pACount) THEN
GetPanelState := pAs[id].Flags
ELSE GetPanelState := -1;
END;
FUNCTION tToolBox.GetFocus : INTEGER;
(*--------------------------------------------------------*)
(* Liefert die ID des Panels, das momentan den Focus hat. *)
(* Gibt -1 zurⁿck, wenn die ID ungⁿltig ist oder das *)
(* Fenster den Stil tbs_MultiSel hat. *)
BEGIN
IF tbStyle AND tbs_MultiSel <> 0 THEN GetFocus := -1
ELSE GetFocus := Focus;
END;
FUNCTION tToolBox.SetPanelState(id : INTEGER;
aStatus: INTEGER) : INTEGER;
(*--------------------------------------------------------*)
(* Setzt den Status des ⁿbergebenen Elementes und zeichnet*)
(* es neu. Liefert -1, falls eine ungⁿltige ID oder ein *)
(* ungⁿltiger Status ⁿbergeben wird oder das angegebene *)
(* Panel momentan den Focus hat. *)
BEGIN
IF (id >= 0) AND (id < pACount) THEN BEGIN
(* Das Panel mit dem Fokus darf nicht geΣndert werden! *)
IF tbStyle AND tbs_MultiSel = 0 THEN
IF GetFocus = id THEN BEGIN
SetPanelState := -1;
Exit;
END;
SetPanelState := 0;
DrawPanel(0, id, aStatus);
END
ELSE SetPanelState := -1;
END;
FUNCTION tToolBox.SetPanel(id : INTEGER;
ResID: INTEGER): INTEGER;
(*--------------------------------------------------------*)
(* ─ndert die Bitmap-Darstellung des Panels ID. Dazu wird *)
(* die Bitmap mit der Ressource-ID ResID verwendet. *)
(* Liefert einen Wert < 0, wenn ID einen ungⁿltigen Wert *)
(* reprΣsentiert oder das Panel momentan des Focus hat. *)
VAR
COfs : WORD;
BEGIN
IF (id >= 0) AND (id < pACount) THEN BEGIN
(* Das Panel mit dem Fokus darf nicht geΣndert werden *)
IF tbStyle AND tbs_MultiSel = 0 THEN
IF GetFocus = id THEN BEGIN
SetPanel := -1;
Exit;
END;
SetPanel := 0;
WITH pAs[id] DO BEGIN
IF hBM <> 0 THEN DeleteObject(hBM);
IF hBMSel <> 0 THEN DeleteObject(hBMSel);
IF UseLowRes THEN COfs := LowResOfs ELSE COfs := 0;
rID := ResID;
hBM := LoadBitmap(hInstance,
MakeIntResource(rID + COfs));
hBMSel := LoadBitmap(hInstance,
MakeIntResource(SecPanelOfs + rID + COfs));
IF (hBM = 0) THEN Flags := tb_Null
ELSE Flags := tb_Normal;
DrawPanel(0, id, Flags);
END;
END
ELSE SetPanel := -1;
END;
FUNCTION tToolBox.InsertPanel(id : INTEGER;
ResID: INTEGER): INTEGER;
(*--------------------------------------------------------*)
(* Fⁿgt ein neues Panel in das Fenster ein. ID bezeichnet *)
(* die Position des neuen Panels, ResID ist der Name der *)
(* ersten Bitmap. Liefert -1 bei ungⁿltiger ID/ResID. *)
VAR
COfs : WORD;
BEGIN
IF (id >= 0) AND (id < Rows*Cols)
AND (pAs[id].hBM = 0) THEN BEGIN
Inc(pACount);
InsertPanel := 0;
WITH pAs[id] DO BEGIN
IF UseLowRes THEN COfs := LowResOfs ELSE COfs := 0;
rID := ResID;
hBM := LoadBitmap(hInstance,
MakeIntResource(rID + COfs));
hBMSel := LoadBitmap(hInstance,
MakeIntResource(SecPanelOfs + rID + COfs));
(* Bitmap nicht gefunden *)
IF (hBM = 0) THEN BEGIN
Flags := tb_Null;
InsertPanel := -1;
END ELSE BEGIN
(* Focus setzen, wenn dieser noch ungⁿltig ist *)
IF (Focus = -1) AND
(tbStyle AND tbs_MultiSel = 0) THEN BEGIN
Focus := id;
Flags := tb_Selected;
END ELSE Flags := tb_Normal;
END;
DrawPanel(0, id, Flags);
END; (* WITH *)
END ELSE InsertPanel := -1;
END;
PROCEDURE tToolBox.DrawEmptyPanel(VAR dc: HDC;
x, y, w, h: INTEGER);
(*--------------------------------------------------------*)
(* Wird aufgerufen, wenn ein ╗leeres½ Panel zu zeichnen *)
(* ist. *)
(* DC : Device-Kontext *)
(* x, y : Obere linke Ecke des Rechtecks *)
(* w, h : Breite und H÷he des zu zeichnenden Bereiches *)
VAR
OPen : hPen;
Pen : hPen;
OBrush: HBrush;
Brush : HBrush;
BEGIN
Brush := CreateSolidBrush(GetNearestColor
(dc, RGB( 193, 193, 193)));
OBrush := SelectObject(dc, Brush);
Pen := CreatePen(ps_Solid, 1,
GetNearestColor(dc, RGB(193, 193, 193)));
OPen := SelectObject(dc, Pen);
Rectangle(dc, x, y, x + w, y + h);
SelectObject(dc, OPen);
DeleteObject(Pen);
SelectObject(dc, OBrush);
DeleteObject(Brush);
END;
PROCEDURE tToolBox.NotifyParent(PanelID, Msg: INTEGER);
(*--------------------------------------------------------*)
(* Sendet eine Nachricht an das Parent-Window. Basierend *)
(* auf der ID des TB-Windows und der ID des Paneles. *)
BEGIN
IF tbStyle AND tbs_MultiMsg <> 0 THEN
(* Fⁿr jedes Panel eine eigene Botschaft *)
SendMessage(Parent^.hWindow, wm_First + wm_User +
pId + PanelID, Msg, pAs[PanelID].rID)
ELSE
(* Sammelbotschaft *)
SendMessage(Parent^.hWindow, wm_First + wm_User + pId,
Msg, LONGINT(PanelID) SHL 16 OR pAs[PanelID].rID);
END;
PROCEDURE tToolBox.DrawPanel(dc: HDC; id, Mode: INTEGER);
(*--------------------------------------------------------*)
(* Zeichnet das Element ID und setzt das Statusfeld des *)
(* Elementes auf Mode. Wird in DC 0 ⁿbergeben, holt sich *)
(* die Funktion einen eigenen Device Context. *)
CONST
(* Brush-Pattern fⁿr Disabled-Items *)
Pattern : ARRAY[0..7] OF WORD =
($AA, $55, $AA, $55, $AA, $55, $AA, $55);
VAR
MemDC : HDC;
x, y : INTEGER;
State : INTEGER;
MadeDC : BOOLEAN;
hBM : hBitmap;
hOBrush: HBrush;
hHBrush: HBrush;
BEGIN
x := (id MOD Cols) * bm_Width;
y := id DIV Cols * bm_Height;
IF dc = 0 THEN BEGIN
dc := GetDC(hWindow);
MadeDC := TRUE
END ELSE MadeDC := FALSE;
(* Leeres Panel *)
IF pAs[id].Flags = tb_Null THEN BEGIN
DrawEmptyPanel(dc, x, y, bm_Width, bm_Height);
IF MadeDC THEN ReleaseDC(hWindow, dc);
Exit;
END;
MemDC := CreateCompatibleDC(dc);
IF (Mode = tb_Normal) OR (Mode = tb_Disabled) THEN
SelectObject(MemDC, pAs[id].hBM)
ELSE IF Mode = tb_Selected THEN
SelectObject(MemDC, pAs[id].hBMSel)
ELSE IF Mode = tb_Toggle THEN BEGIN
State := GetPanelState(id);
IF State = tb_Selected THEN BEGIN
Mode := tb_Normal;
SelectObject(MemDC, pAs[id].hBM)
END ELSE IF State = tb_Normal THEN BEGIN
Mode := tb_Selected;
SelectObject(MemDC, pAs[id].hBMSel)
END ELSE Mode := tb_Disabled;
END ELSE IF Mode = tb_Null THEN BEGIN
DrawEmptyPanel(dc, x, y, bm_Width, bm_Height);
END;
pAs[id].Flags := Mode;
BitBlt(dc, x, y,bm_Width, bm_Height,
MemDC, 0, 0, SrcCopy);
IF Mode = tb_Disabled THEN BEGIN
(* Dithered-Darstellung *)
hBM := CreateBitmap(8, 8, 1, 1, @Pattern);
hHBrush := CreatePatternBrush(hBM);
hOBrush := SelectObject(dc,hHBrush);
BitBlt(dc, x, y, bm_Width, bm_Height,
MemDC, 0, 0, MergeCopy);
SelectObject(dc, hOBrush);
DeleteObject(hHBrush);
DeleteObject(hBM);
END;
DeleteDC(MemDC);
IF MadeDC THEN ReleaseDC(hWindow,dc);
END;
PROCEDURE tToolBox.Paint(PaintDC: HDC;
VAR PaintInfo: tPaintStruct);
(*--------------------------------------------------------*)
(* Zeichnet den Hintergrund und alle Panels neu. *)
VAR i : INTEGER;
BEGIN
tWindow.Paint(PaintDC,PaintInfo);
FOR i := 0 TO Rows * Cols - 1 DO
DrawPanel(PaintDC, i,pAs[i]. Flags)
END;
PROCEDURE tToolBox.wmMove (VAR Msg: tMessage);
(*--------------------------------------------------------*)
(* Speichert beim Bewegen des Fensters die neuen *)
(* Koordinaten in xClient und yClient. *)
BEGIN
xClient := INTEGER(Msg.lParamLo);
yClient := INTEGER(Msg.lParamHi);
tWindow.wmMove(Msg);
END;
PROCEDURE tToolBox.wmMouseMove(VAR Msg: tMessage);
(*--------------------------------------------------------*)
(* Verfolgt die Mausbewegungen bei gedrⁿckter link. Taste *)
VAR
r : tRect;
pt : tPoint;
BEGIN
(* Linke Taste mu▀ innerhalb des TB-Windows gedrⁿckt *)
(* worden sein! *)
IF NOT InWindow OR (Msg.wParam AND mk_LButton = 0) OR
IsIconic(hWindow) THEN Exit;
GetClientRect(hWindow,r);
pt.x := INTEGER(Msg.lParamLo);
pt.y := INTEGER(Msg.lParamHi);
IF NOT PtInRect(r,pt) THEN
(* Au▀erhalb des Fensters *)
DrawPanel(0, MsDnID, ActState)
ELSE BEGIN
(* Innerhalb => Panel-ID berechnen *)
IF (Msg.lParamLo DIV bm_Width) +
(Cols*(Msg.lParamHi DIV bm_Height)) <> MsDnID THEN
(* Nicht dasselbe Panel wie bei MsDown *)
DrawPanel(0,MsDnID,ActState)
ELSE BEGIN
(* Im neuen Zustand zeichen *)
IF ActState AND tb_Selected <> 0 THEN
DrawPanel(0, MsDnID, tb_Normal)
ELSE
DrawPanel(0, MsDnID, tb_Selected);
END;
END;
END;
PROCEDURE tToolBox.wmlButtonDown(VAR Msg: tMessage);
(*--------------------------------------------------------*)
(* Speichert die Maus-Koordinaten beim Drⁿcken der Taste *)
(* und zeichnet das Panel neu. *)
BEGIN
IF IsIconic(hWindow) THEN Exit;
(* Linke Taste innerhalb des FM-Windows gedrⁿckt *)
InWindow := TRUE;
BringWindowToTop(hWindow);
MsDnID := (Msg.lParamLo DIV bm_Width) +
(Cols * (Msg.lParamHi DIV bm_Height));
(* Status des Panels beim Drⁿcken merken *)
ActState := pAs[MsDnID].Flags;
IF (ActState = tb_Disabled) OR
(ActState = tb_Null) THEN BEGIN
(* Ungⁿltige Position/Panelzustand *)
MessageBeep(0);
InWindow := FALSE;
END;
DrawPanel(0, MsDnID, tb_Toggle);
(* Alle Mausnachrichten gehen ab jetzt an das FM-Fenster *)
SetCapture(hWindow);
tWindow.wmlButtonDown(Msg);
END;
PROCEDURE tToolBox.wmlButtonUp(VAR Msg: tMessage);
(*--------------------------------------------------------*)
(* Verarbeitet das Loslassen der Taste. Stellt den Status *)
(* fest und sendet einen Nachricht an das Eltern-Fenster. *)
VAR
i, j : INTEGER;
r : tRect;
pt : tPoint;
BEGIN
IF IsIconic(hWindow) THEN Exit;
InWindow := FALSE;
ReleaseCapture;
GetClientRect(hWindow,r);
pt.x := INTEGER(Msg.lParamLo);
pt.y := INTEGER(Msg.lParamHi);
(* Nur wenn Maus im Fenster *)
IF PtInRect(r,pt) THEN BEGIN
i := (Msg.lParamLo DIV bm_Width) +
(Cols * (Msg.lParamHi DIV bm_Height));
IF i = MsDnID THEN BEGIN
(* Gleiche Position wie bei MsDown *)
pAs[i].Flags := ActState;
IF tbStyle AND tbs_MultiSel <> 0 THEN BEGIN
(* MultiSel *)
IF pAs[i].Flags = tb_Selected THEN BEGIN
DrawPanel(0, i, tb_Normal);
NotifyParent(i, tbm_Unselect);
END ELSE IF pAs[i].Flags = tb_Normal THEN BEGIN
DrawPanel(0, i, tb_Selected);
NotifyParent(i, tbm_Select);
END;
END ELSE BEGIN (* Single *)
(* Fokus Σndern *)
IF (pAs[i].Flags <> tb_Disabled) AND
(pAs[i].Flags <> tb_Null) THEN BEGIN
DrawPanel(0, Focus, tb_Normal);
DrawPanel(0, i, tb_Selected);
IF i <> Focus THEN BEGIN
NotifyParent(Focus, tbm_Unselect);
NotifyParent(i, tbm_Select);
END;
END ELSE i := Focus;
END;
Focus := i;
END; (* i = MsDnID *)
END; (* PtInRect *)
END;
END.
(**********************************************************)
(* Ende von TBWIN.PAS *)