Hi,
has anyone a good idea, how to design an app with this requirements:
- one finished exe (the main window - with general stuff)
- From time to time I will add differents "objects" with different "methodes" (maybe in different windows with different Gadgets), which need to do something with the main exe...
Is there simple way?
Til now, I added always new stuff into the main code, compiled it and exchanged the exe.
I don`t want to do this anymore.
I hope, you know, what I mean....
br and thx
How to design an app with "dynamic external objects"?
How to design an app with "dynamic external objects"?
PureBasic for Windows
-
Zach
- Addict

- Posts: 1678
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: How to design an app with "dynamic external objects"?
DLL-based plugin system ?
Re: How to design an app with "dynamic external objects"?
I'm currently doing the same what you want to do: Making an application extendable dynamically.
But: A lot of stuff is different from a normal application with static content. At the German PureBasic forums I've asked about the events of gadgets, because they where not handled like I want it should handle it... However the code may be useful for you: http://forums.purebasic.com/german/view ... =3&t=23748
The code from the post above with some bug fixes:
Main application:
DLL (Child.dll):
The code has one known bug: If you click on the first button which is handled by the main application, the event only occurs if you move the mouse away from the button. The second button is handled by the DLL because the gadget is in another gadget (ContainerGadget).
But: A lot of stuff is different from a normal application with static content. At the German PureBasic forums I've asked about the events of gadgets, because they where not handled like I want it should handle it... However the code may be useful for you: http://forums.purebasic.com/german/view ... =3&t=23748
The code from the post above with some bug fixes:
Main application:
Code: Select all
Enumeration
#Window
#Menu
#MDI
#Dll
EndEnumeration
If OpenWindow(#Window,100,100,600,400,"Main App",#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget)
If CreateMenu(#Menu,WindowID(#Window))
MenuTitle("MDI")
EndIf
MDIGadget(#MDI,0,0,0,0,0,0,#PB_MDI_AutoSize)
Window=AddGadgetItem(#MDI,#PB_Any,"Child DLL")
If OpenLibrary(#Dll,"Child.dll")
CallFunction(#Dll,"AddObjects",WindowID(Window))
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
MessageRequester("Gadget Event","Gadget: "+Str(EventGadget()))
Case #PB_Event_CloseWindow
If EventWindow()=#Window
Quit=#True
EndIf
EndSelect
Until Quit
CallFunction(#Dll,"Unload")
CloseWindow(Window)
CloseLibrary(Dll)
EndIf
EndIfCode: Select all
Global ThreadID
Global Unload.b
Procedure ChildWindow(ChildWindowID)
OpenWindow(0,0,0,0,0,"",#PB_Window_Invisible)
UseGadgetList(ChildWindowID)
ButtonGadget(#PB_Any,10,10,100,30,"Button 1")
ContainerGadget(#PB_Any,10,50,120,50,#PB_Container_Flat)
ButtonGadget(#PB_Any,10,10,100,30,"Button 2")
CloseGadgetList()
Repeat
Select WaitWindowEvent(5)
Case #PB_Event_Gadget
MessageRequester("Child Gadget Event","Gadget: "+Str(EventGadget()))
EndSelect
Until Unload
EndProcedure
ProcedureDLL AddObjects(ChildWindowID)
ThreadID=CreateThread(@ChildWindow(),ChildWindowID)
EndProcedure
ProcedureDLL Unload()
Unload=#True
WaitThread(ThreadID,3000)
If IsThread(ThreadID)
KillThread(ThreadID)
EndIf
EndProcedureRe: How to design an app with "dynamic external objects"?
Isn't this the same problem as creating a dynamic menu? Like a MRU list?
For a dynamic menu, I have to add the new menu elements and then recreate the entire menu on the target window.
The menu specifics are stored in a structured array.
For a dynamic GUI, I do the same.
The structured gadget array is obviously more complex, but not too much.
Have a look at the native gadget creation commands. There are many common properties.
Store the static GUI contents in an external file or DataSection(according to gadget type: W-window, ED-Editor,BU-Button,etc.) and then append the new dynamic contents to the gad(). Hide the target window and repopulate according to the gadgets in gad(). And you must use #PB_Any. You will have to add Open and CloseGadgetList's depending on your gadget nesting.
This only populates the GUI. It does not create the Event handlers.
Think how the Visual Designers work?
They create the same dynamic GUI based on user point and click, but output #Enumerations for the gadgets created.
If you create the GUI dynamically, then you have the gad(i)\id's already in an array to process in your Events sections.
For a dynamic menu, I have to add the new menu elements and then recreate the entire menu on the target window.
The menu specifics are stored in a structured array.
For a dynamic GUI, I do the same.
The structured gadget array is obviously more complex, but not too much.
Have a look at the native gadget creation commands. There are many common properties.
Store the static GUI contents in an external file or DataSection(according to gadget type: W-window, ED-Editor,BU-Button,etc.) and then append the new dynamic contents to the gad(). Hide the target window and repopulate according to the gadgets in gad(). And you must use #PB_Any. You will have to add Open and CloseGadgetList's depending on your gadget nesting.
Code: Select all
; snippet...
With gad(i)
\id = OpenWindow(#PB_Any, \x, \y, \wd, \ht, \Txt, \Flags|#PB_Window_Invisible)
\id = ButtonGadget(#PB_Any, \X, \Y, \Wd, \Ht, \Txt, \Flags)
\id = CalendarGadget(#PB_Any,\X, \Y, \Wd, \Ht, #Null, \Flags)
\id = EditorGadget(#PB_Any, \x, \y, \Wd, \Ht, \Flags)
\id = ListViewGadget(#PB_Any,\x, \y, \Wd, \Ht, \Flags)
;...and so on...
EndWith
Think how the Visual Designers work?
They create the same dynamic GUI based on user point and click, but output #Enumerations for the gadgets created.
If you create the GUI dynamically, then you have the gad(i)\id's already in an array to process in your Events sections.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: How to design an app with "dynamic external objects"?
And... the Visual Design doesn't handle events.skywalk wrote:This only populates the GUI. It does not create the Event handlers.
Think how the Visual Designers work?
They create the same dynamic GUI based on user point and click, but output #Enumerations for the gadgets created.
If you create the GUI dynamically, then you have the gad(i)\id's already in an array to process in your Events sections.
Just gadgets without events makes no sense.
Re: How to design an app with "dynamic external objects"?
Well of course. You still have to create the Event code, but you have all the new recipients of messages in the gad() array.Programie wrote:Just gadgets without events makes no sense.
The response to those messages cannot totally be automated. That is the heart of your code.
Code: Select all
; snippet...
Case #PB_Event_Gadget
evG = EventGadget()
evT = EventType()
If evG = gad(i)\id ; 'i' can be substituted for custom enumerations based on your desired algorithm.
; i = #Window_GadgetType_Description = #MainW_PANEL_ADDRESS
; Panel selected/changed on Main Window
; Do something...
EndIf
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
-
Zach
- Addict

- Posts: 1678
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: How to design an app with "dynamic external objects"?
I could be going way off the rails here.
But what about using XML based configuration files? Or some other format that could be easily and quickly parsed (you'd still have to write a parser).
If the GUI elements and events were configured in this way, you might end up with a nearly-realtime dynamic system? Perhaps throwing scripts into the mix if necesarry.
I don't know how complex the application you are writing is, or what its intended to do but it was just a thought that came to me.
The idea being, if your app is parsing said files at run time, you could have it re-parsing the files not every cycle, but every so often.. Or alternatively (or in addition to re-parse checks) setup a GUI command/Hotkey command that will instruct the program to re-parse its config files on demand. Perhaps start it off with a check against file size (open the files, parse them, then close them); so it checks that the file has changed size and proceeds to open the file again and parse it to update what the program is doing. So then the GUI could be re-drawn if needed and new events would be listened for, etc.. That mainly works for something like a GUI, but I'm not sure how well that would work for adding actual functionality (i.e code) which is where scripts could also come in I guess. An embeddable language like Python or LUA, etc. might come in handy there.
But that may be an oversimplification of a complex implementation to actually attempt...
XML + DLL files may be a better approach versus scripting though. If you skeleton the GUI and events with XML, that leaves the door open for you to write in the appropriate calls to the new DLL functions from your GUI elements. Then either manually trigger a re-parse, or wait for a re-parse check to pick up the changes.
Anyway just an idea I had. Maybe it will give you a better idea?
But what about using XML based configuration files? Or some other format that could be easily and quickly parsed (you'd still have to write a parser).
If the GUI elements and events were configured in this way, you might end up with a nearly-realtime dynamic system? Perhaps throwing scripts into the mix if necesarry.
I don't know how complex the application you are writing is, or what its intended to do but it was just a thought that came to me.
The idea being, if your app is parsing said files at run time, you could have it re-parsing the files not every cycle, but every so often.. Or alternatively (or in addition to re-parse checks) setup a GUI command/Hotkey command that will instruct the program to re-parse its config files on demand. Perhaps start it off with a check against file size (open the files, parse them, then close them); so it checks that the file has changed size and proceeds to open the file again and parse it to update what the program is doing. So then the GUI could be re-drawn if needed and new events would be listened for, etc.. That mainly works for something like a GUI, but I'm not sure how well that would work for adding actual functionality (i.e code) which is where scripts could also come in I guess. An embeddable language like Python or LUA, etc. might come in handy there.
But that may be an oversimplification of a complex implementation to actually attempt...
XML + DLL files may be a better approach versus scripting though. If you skeleton the GUI and events with XML, that leaves the door open for you to write in the appropriate calls to the new DLL functions from your GUI elements. Then either manually trigger a re-parse, or wait for a re-parse check to pick up the changes.
Anyway just an idea I had. Maybe it will give you a better idea?





