(fast) jeder kennt bekanntlich das kleine Beispiel aus dem PureArchive bei dem ein Dialog geöffnet wird. So bald man irgendein Button anklickt, dann verschwindet dieser wieder sofort.
Natürlich kann man in dieser ganzen Zeit im Main- bzw. Hauptfenster keine einzige Aktion ausführen. Das ist kein Bug, sondern eben das Feature eines Dialoges, welches Purebasic momentan (leider noch) nicht beherrscht.
Eventuell ist das sogar wegen der Betriebssystem-Unabhängigkeit gewollt, oder weil der Entwickler will das die Programme mit Purebasic ziemlich Flexibel in der Bedienung sein sollen (z.B. kann man im Purebasic Editor den Quellcode bearbeiten während das "Suchen"-Fenster geöffnet ist). Wie dem auch sei...
Ich habe nun eine kleine Library zusammengebastelt die jeder Fortgeschrittene schnell zusammenschustern kann. Allerdings hat sicherlich fast jeder hier mit seiner eigenen Libr. aufgegeben als das Thema Event-Handling angesagt war.
Erst recht, wenn dann auch noch weitere Dialoge aus einen Dialog heraus zu öffnen sein sollen.
Keine Angst, ich habe nicht aufgegeben. Das heißt: Diese Library unterstützt Rekursives öffnen von Dialogen mit entsprechendes Event-Handling und ermöglicht (bei richtiger Nutzung) sogar etwas Objekt-Orientiertes Programmieren wie in z.B. Delphi/Borland C++ Builder. Denn man kann für jedes Dialog einzelne Prozeduren als Pointer übergeben, welche z.B. bei einer Handlung, nach dem Erstellen oder auch beim Schließen aufgerufen werden sollen.
Man mache sich mal klar, dass man einzelne Events Kapsel kann ohne eine extra Funktion außerhalb eines Event-Aufrufs schreiben zu müssen.
Wie das nun Effektiv sein kann, kann man nun im folgenden Quellcode sehen. Weiter unten ist dann auch der Quellcode zur Library.
Sonntag, 17. Juni 2007
* In Gedanken hatte ich #AdvDlg_Proc_Update benutzt, obwohl eigentlich nur #WM_COMMAND abgefragt wird. Dieser Fehler ist behoben. #AdvDlg_Proc_Update existiert nicht mehr und heißt nun #AdvDlg_Proc_Command .
* Ab jetzt muss man immer vor den Setzen von Events und dem Erstellen eines Dialogs, die Funktion AdvDlg_Init() aufrufen. z.B.
Code: Alles auswählen
AdvDlg_Init()
AdvDlg_SetProc( #AdvDlg_Proc_Open, @MyDialog_C_Open() )
AdvDlg_SetProc( #AdvDlg_Proc_Command, @MyDialog_C_Command() )
AdvDlg_SetProc( #AdvDlg_Proc_Close, @MyDialog_C_Close() )
AdvDlg_SetApiProc( #WM_LBUTTONDOWN, @MyDialog_ShowMessageOnClick() )
*MyDialog_C = AdvDlg_Create( AdvDlg_GethWnd(), 0, 0, 100, 200, "Sample Dialog 3", #WS_POPUP | #WS_BORDER | #WS_SYSMENU | #DS_MODALFRAME | #WS_CAPTION | #DS_CENTER )
Nun zu den Quellcodes:
Code: Alles auswählen
; AdvancedDialog_Sample.pb V1.1
; by ShadowTurtle @ Sonntag, 14. Juni 2007
;XIncludeFile("AdvancedDialog.pb")
Procedure MyDialog_ShowMessageOnClick()
MessageRequester("blob", "bla")
EndProcedure
Procedure MyDialog_C_Open()
ButtonGadget(5,20,50,100,22,"This was it!")
ButtonGadget(6,20,80,100,22,"Close")
EndProcedure
Procedure MyDialog_C_Command()
GadgetID = AdvDlg_GetGadgetID()
If GadgetID = 6
AdvDlg_Close()
EndIf
EndProcedure
Procedure MyDialog_C_Close()
EndProcedure
Procedure MyDialog_B_Open()
ButtonGadget(3,20,50,100,22,"Open Dialog Nr. 3")
ButtonGadget(4,20,80,100,22,"Close")
EndProcedure
Procedure MyDialog_B_Command()
GadgetID = AdvDlg_GetGadgetID()
If GadgetID = 3
AdvDlg_Init()
AdvDlg_SetProc( #AdvDlg_Proc_Open, @MyDialog_C_Open() )
AdvDlg_SetProc( #AdvDlg_Proc_Command, @MyDialog_C_Command() )
AdvDlg_SetProc( #AdvDlg_Proc_Close, @MyDialog_C_Close() )
AdvDlg_SetApiProc( #WM_LBUTTONDOWN, @MyDialog_ShowMessageOnClick() )
*MyDialog_C = AdvDlg_Create( AdvDlg_GethWnd(), 0, 0, 100, 200, "Sample Dialog 3", #WS_POPUP | #WS_BORDER | #WS_SYSMENU | #DS_MODALFRAME | #WS_CAPTION | #DS_CENTER )
EndIf
If GadgetID = 4
AdvDlg_Close()
EndIf
EndProcedure
Procedure MyDialog_B_Close()
EndProcedure
Procedure MyDialog_A_Open()
ButtonGadget(1,20,50,100,22,"Open Dialog Nr. 2")
ButtonGadget(2,20,80,100,22,"Close")
EndProcedure
Procedure MyDialog_A_Command()
GadgetID = AdvDlg_GetGadgetID()
If GadgetID = 1
AdvDlg_Init()
AdvDlg_SetProc( #AdvDlg_Proc_Open, @MyDialog_B_Open() )
AdvDlg_SetProc( #AdvDlg_Proc_Command, @MyDialog_B_Command() )
AdvDlg_SetProc( #AdvDlg_Proc_Close, @MyDialog_B_Close() )
AdvDlg_SetApiProc( #WM_LBUTTONDOWN, @MyDialog_ShowMessageOnClick() )
*MyDialog_B = AdvDlg_Create( AdvDlg_GethWnd(), 0, 0, 150, 250, "Sample Dialog 2", #WS_POPUP | #WS_BORDER | #WS_SYSMENU | #DS_MODALFRAME | #WS_CAPTION | #DS_CENTER )
EndIf
If GadgetID = 2
AdvDlg_Close()
EndIf
EndProcedure
Procedure MyDialog_A_Close()
EndProcedure
OpenWindow(0, 325, 185, 600, 330, "Main Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar )
AdvDlg_Init()
AdvDlg_SetProc( #AdvDlg_Proc_Open, @MyDialog_A_Open() )
AdvDlg_SetProc( #AdvDlg_Proc_Command, @MyDialog_A_Command() )
AdvDlg_SetProc( #AdvDlg_Proc_Close, @MyDialog_A_Close() )
AdvDlg_SetApiProc( #WM_LBUTTONDOWN, @MyDialog_ShowMessageOnClick() )
*MyDialog_A = AdvDlg_Create(WindowID(0), 0, 0, 200, 300, "Sample Dialog 1", #WS_POPUP | #WS_BORDER | #WS_SYSMENU | #DS_MODALFRAME | #WS_CAPTION | #DS_CENTER )
Repeat
Event = WaitWindowEvent()
WindowID = EventWindow()
GadgetID = EventGadget()
EventType = EventType()
If Event = #PB_Event_Gadget
Debug GadgetID
EndIf
Until Event = #PB_Event_CloseWindow
End
Code: Alles auswählen
; AdvancedDialog.pb V1.1
; by ShadowTurtle @ Sonntag, 14. Juni 2007
Structure AdvDialog
*Template.AdvDlg_Template
*Proc
ParWinID.l
Title.s
hWnd.l
uMsg.l
wParam.l
lParam.l
EndStructure
Structure AdvDlg_Template
style.l
dwExtendedStyle.l
cdit.w
x.w
y.w
cx.w
cy.w
menu.w
class.w
title.l
EndStructure
Structure AdvDlg_DataStore
*AdvDlg.AdvDialog
*AdvDlgProcs[11]
*AdvDlgApiProc.AdvDlg_ApiProc
EndStructure
Structure AdvDlg_ApiProc
ApiMsg.l
*Proc
*NextProc.AdvDlg_ApiProc
EndStructure
Global *AdvDlg.AdvDialog
Dim *AdvDlgProcs(11)
Global *AdvDlgApiProc.AdvDlg_ApiProc
*AdvDlgApiProc = 0
Declare AdvDlg_AddDatas__()
Declare AdvDlg_SetBackDatas__()
Dim *AdvDlg_DialogsList(11)
Global AdvDlg_DialogsInList
AdvDlg_DialogsInList = 0
#AdvDlg_Proc_Open = 0
#AdvDlg_Proc_Command = 1
#AdvDlg_Proc_Close = 2
Procedure AdvDlg_Proc( hWnd, uMsg, wParam, lParam )
Shared *AdvDlg.AdvDialog
Shared *AdvDlgProcs()
Select uMsg
Case #WM_INITDIALOG
*AdvDlg\uMsg = uMsg
*AdvDlg\wParam = wParam
*AdvDlg\lParam = lParam
CreateGadgetList(hWnd)
SetWindowText_(hWnd, *AdvDlg\Title )
*AdvDlg\hWnd = hWnd
If Not *AdvDlgProcs(0) = 0
*RunProc = *AdvDlgProcs(0)
CallFunctionFast(*RunProc)
EndIf
Case #WM_COMMAND
*AdvDlg\uMsg = uMsg
*AdvDlg\wParam = wParam
*AdvDlg\lParam = lParam
If Not *AdvDlgProcs(1) = 0
*RunProc = *AdvDlgProcs(1)
CallFunctionFast(*RunProc)
EndIf
Case #WM_CLOSE
*AdvDlg\uMsg = uMsg
*AdvDlg\wParam = wParam
*AdvDlg\lParam = lParam
If Not *AdvDlgProcs(2) = 0
*RunProc = *AdvDlgProcs(2)
CallFunctionFast(*RunProc)
EndIf
EndDialog_(hWnd,wParam&$FFFF)
Default:
*ApiPrc.AdvDlg_ApiProc = *AdvDlgApiProc
While Not *ApiPrc = 0
If *ApiPrc\ApiMsg.l = uMsg
CallFunctionFast(*ApiPrc\Proc)
EndIf
*ApiPrc = *ApiPrc\NextProc
Wend
EndSelect
ProcedureReturn 0
EndProcedure
Procedure AdvDlg_Init()
*AdvDlgApiProc = 0
EndProcedure
Procedure.l AdvDlg_Create(ParentWinID, px.w, py.w, sx.w, sy.w, Title.s, style.l = -1)
If style.l = -1
style.l = #WS_POPUP | #WS_BORDER | #WS_SYSMENU | #DS_MODALFRAME | #WS_CAPTION | #DS_CENTER
EndIf
*DlgTemp.AdvDlg_Template = AllocateMemory(SizeOf(AdvDlg_Template))
*DlgTemp\style = style
*DlgTemp\x = px
*DlgTemp\y = py
*DlgTemp\cx = sx/2
*DlgTemp\cy = sy/2
*AdvDlg.AdvDialog = AllocateMemory(SizeOf(AdvDialog))
*AdvDlg\Title = Title
*AdvDlg\Template = *DlgTemp
*AdvDlg\ParWinID = ParentWinID
*AdvDlg\Proc = *Proc
AdvDlg_AddDatas__()
Result = DialogBoxIndirectParam_(0, *DlgTemp, ParentWinID, @AdvDlg_Proc(), 0)
*ApiPrc.AdvDlg_ApiProc = *AdvDlgApiProc
While Not *ApiPrc = 0
*NxtApiPrc = *ApiPrc\NextProc
FreeMemory(*ApiPrc)
*ApiPrc = *NxtApiPrc
Wend
FreeMemory(*AdvDlg\Template)
FreeMemory(*AdvDlg)
AdvDlg_SetBackDatas__()
ProcedureReturn( Result )
EndProcedure
Procedure AdvDlg_SetProc(ProcID, *ProcPointer)
Shared *AdvDlg.AdvDialog
Shared *AdvDlgProcs()
*AdvDlgProcs(ProcID) = *ProcPointer
EndProcedure
Procedure AdvDlg_SetApiProc(ApiMsg, *ProcPointer)
*ApiPrc.AdvDlg_ApiProc = AllocateMemory(SizeOf(AdvDlg_ApiProc))
*ApiPrc\ApiMsg = ApiMsg
*ApiPrc\Proc = *ProcPointer
*ApiPrc\NextProc = *AdvDlgApiProc
*AdvDlgApiProc = *ApiPrc
EndProcedure
Procedure AdvDlg_GetGadgetID()
Shared *AdvDlg.AdvDialog
ProcedureReturn( *AdvDlg\wParam&$FFFF )
EndProcedure
Procedure AdvDlg_GethWnd()
Shared *AdvDlg.AdvDialog
ProcedureReturn( *AdvDlg\hWnd )
EndProcedure
Procedure AdvDlg_Close()
Shared *AdvDlg.AdvDialog
Shared *AdvDlgProcs()
If Not *AdvDlgProcs(2) = 0
*RunProc = *AdvDlgProcs(2)
CallFunctionFast(*RunProc)
EndIf
EndDialog_(*AdvDlg\hWnd,wParam&$FFFF)
EndProcedure
Procedure AdvDlg_AddDatas__()
Shared *AdvDlg.AdvDialog
Shared *AdvDlgProcs()
Shared AdvDlg_DialogsInList
Shared *AdvDlg_DialogsList()
*ListEntry.AdvDlg_DataStore = AllocateMemory(SizeOf(AdvDlg_DataStore))
*ListEntry\AdvDlg = *AdvDlg
For I = 0 To 10
*ListEntry\AdvDlgProcs[I] = *AdvDlgProcs(I)
Next
*ListEntry\AdvDlgApiProc = *AdvDlgApiProc
*AdvDlg_DialogsList(AdvDlg_DialogsInList) = *ListEntry
AdvDlg_DialogsInList = AdvDlg_DialogsInList + 1
EndProcedure
Procedure AdvDlg_SetBackDatas__()
Shared *AdvDlg.AdvDialog
Shared *AdvDlgProcs()
Shared AdvDlg_DialogsInList
Shared *AdvDlg_DialogsList()
If AdvDlg_DialogsInList > 1
AdvDlg_DialogsInList = AdvDlg_DialogsInList - 1
*ListEntry.AdvDlg_DataStore = *AdvDlg_DialogsList(AdvDlg_DialogsInList-1)
*AdvDlg = *ListEntry\AdvDlg
For I = 0 To 10
*AdvDlgProcs(I) = *ListEntry\AdvDlgProcs[I]
Next
*AdvDlgApiProc = *ListEntry\AdvDlgApiProc
Else
AdvDlg_DialogsInList = 0
EndIf
EndProcedure