Page 1 of 1

A smart Eventhandler Include for PB

Posted: Sat Jul 21, 2012 2:17 pm
by Kurzer
Hi there,

is there a need for a smart eventhandler include for PB?
I've written such a eventhandler for quite some time for my own use and made the code and documentation public in the german forum. It reduce the administrative expenses in the field of event processing.

As I've recently made an update of the german forum thread, I've noticed that I've not introduced the event handler in the english forum.

Unfortunately, all the descriptions are in german language and I'm not able to do an adequate translation to english
(this post is also partly translated by google translate - I'm sure you realized that already ;-)).
If there is interest in the include code, maybe we found someone who can do the translation.

In this post I once refer to the german thread and give you a short description of the eventhandler commands.

Thread in the german forum: here
Download sourcecode and example code: here


Short description:

1)
After creating your GUI and gadgets you have to assign the needed gadget events to your eventprocedures.
The commands to do this are:
evh_SetWindowEvent(iWindowNr, iEventType, *EventProcedure)
evh_SetMenuEvent (iWindowNr, iMenuitemNr, *EventProcedure)
evh_SetGadgetEvent(iWindowNr, iGadgetNr, iEventType, *EventProcedure)

Example:

; Gadgets
evh_SetGadgetEvent(Window_Main, Window_Main_Button(1), #PB_EventType_LeftClick, @Button1Click())
evh_SetGadgetEvent(Window_Main, Window_Main_Button(2), #PB_EventType_LeftClick, @Button2Click())


; Menus
evh_SetMenuEvent(Window_Main, #MENUPUNKT1, @Menu1())
evh_SetMenuEvent(Window_Main, #MENUPUNKT2, @Menu2())


So each time you click on Window_Main_Button(1) your procedure Button1Click() will be called.
No need to call WaitWindowEvent() in your main programm and no need to check all the events using a big Select-Case-tree in your mainloop.

2)
Your eventprocedures must have one predefined structured parameter:

*stEventArgs.evh_EventArgsstruct

This is a pointer to a structure (predefined by the eventhandler) which contains the following entries:

\iEvent
\iEventType
\iEventWindow
\iEventGadget
\iEventMenu
\iEventTimer
\iEventwParam
\iEventlParam


Example:

Procedure Button1Click(*stEventArgs.evh_EventArgsstruct)
Debug "Button 1 clicked"
EndProcedure

So your Eventprocedure have access to all the relevant data to process the event.
The structure is automatically filled by the event handler and holds the values which are returned by the PB commands WaitWindowEvent(), EventType(), EventWindow() and so on.

3)
The eventloop in your main code is now reduced to this three commands:

While evh_ProcessEvents(25, MainWindow, @OwnEventproc(), 0, 0)
Wend


So you have to call only this one command in your eventloop:
evh_ProcessEvents(iTimeOut, iObserveWindow, [*OwnEventHandler], [*stEvents])

The eventloop will run as long as the window "iObserveWindow" do not receive an CloseWindow event.


You have some more options with this include wich are described in detail in the german forum - sorry for my inadequate english skill.

Here is an short democode. It shows how to use nearly all options of the include in a real condition:

Code: Select all

EnableExplicit

;*************************************************************************
;* Includefiles
;*************************************************************************

IncludeFile "Eventhandler.pb"

;*************************************************************************
;* Variables
;*************************************************************************

Global Window_Main.i, Window_Options.i
Global Dim Window_Main_Buttons.i(10)

Enumeration
   #MENUPUNKT1
   #MENUPUNKT2
EndEnumeration

;*************************************************************************
;* Eventprocddures
;*************************************************************************
Procedure Button1Click(*stEventArgs.evh_EventArgsstruct)
	AddGadgetItem(0, 0, "Button 1 geklickt")
EndProcedure

Procedure Button2Click(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Button 2 geklickt")
EndProcedure

Procedure Button4Click(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Button 4 geklickt")
EndProcedure

Procedure Menu1(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Menüpunkt 1 ausgewählt")
EndProcedure

Procedure Menu2(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Menüpunkt 2 ausgewählt")
EndProcedure

Procedure Window1Timer(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Timeraufruf erfolgte. Timer Nr. " + Str(*stEventArgs\iEventTimer))
EndProcedure

Procedure Window1Activate(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Das Fenster Nr 1 wurde aktiviert")
EndProcedure

Procedure Window2Activate(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Das Fenster Nr 2 wurde aktiviert")
EndProcedure

Procedure Window2Gadget(*stEventArgs.evh_EventArgsstruct)
  AddGadgetItem(0, 0, "Fenster Nr 2, Buttonhandle:" + Str(GadgetID(*stEventArgs\iEventGadget)))
EndProcedure

Procedure CloseMyWindow(*stEventArgs.evh_EventArgsstruct)
  ; Schließen des zweiten Fensters
  If IsWindow(*stEventArgs\iEventWindow) 
  	; Alle registrierten Events von Fenster 2 entfernen
  	evh_RemoveEvent(Window_Options)
  	
		CloseWindow(*stEventArgs\iEventWindow)
		AddGadgetItem(0, 0, "Fenster 2 wurde geschlossen")
	EndIf
EndProcedure

Procedure OwnEventproc(*stEventArgs.evh_EventArgsstruct)
  ; Button 3 wird über die eigene Eventauswertung bearbeitet
  If *stEventArgs\iEvent = #PB_Event_Gadget And *stEventArgs\iEventGadget = Window_Main_Buttons(3) And *stEventArgs\iEventType = #PB_EventType_LeftClick
    AddGadgetItem(0, 0, "Button 3 geklickt")
  EndIf
EndProcedure

;*************************************************************************
;* Open Window
;*************************************************************************

Window_Main = OpenWindow(#PB_Any, 10, 10, 300, 500, "Ein 'Kurzer' Eventhandler ;-)", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_MaximizeGadget)
If Window_Main
    ; Ein Menü erzeugen
  If CreateMenu(0, WindowID(Window_Main))
    MenuTitle("Menüpunkte...")
    MenuItem(#MENUPUNKT1, "Menüpunkt 1")
    MenuItem(#MENUPUNKT2, "Menüpunkt 2")
  EndIf

	; Ein Textfeld für die Meldungen
	EditorGadget(0, 10, 50, 280, 420, #PB_Editor_ReadOnly)

  ; Buttons erzeugen
  Window_Main_Buttons(1) = ButtonGadget(#PB_Any, 100, 10, 50, 30, "Button 1")
  Window_Main_Buttons(2) = ButtonGadget(#PB_Any, 160, 10, 50, 30, "Button 2")
  Window_Main_Buttons(3) = ButtonGadget(#PB_Any, 220, 10, 50, 30, "Button 3")

  ; Hier werden den Gadgets/Menuitems/dem Window die Eventprozeduren zugeordnet
  ; Gadgets
  evh_SetGadgetEvent(Window_Main, Window_Main_Buttons(1), #PB_EventType_LeftClick, @Button1Click())
  evh_SetGadgetEvent(Window_Main, Window_Main_Buttons(2), #PB_EventType_LeftClick, @Button2Click())
	; Menüs
  evh_SetMenuEvent(Window_Main, #MENUPUNKT1, @Menu1())
  evh_SetMenuEvent(Window_Main, #MENUPUNKT2, @Menu2())
  ; Windowevents
  evh_SetWindowEvent(Window_Main, #PB_Event_ActivateWindow, @Window1Activate())
  ; Achtung! Eine Prozedur für alle WindowTimer. Die Timernummer kann aus der Eventstruktur gelesen werden
  evh_SetWindowEvent(Window_Main, #PB_Event_Timer, @Window1Timer())
  
  AddWindowTimer(Window_Main, 0, 3000)
EndIf

Window_Options = OpenWindow(#PB_Any, 320, 10, 150, 50, "Optionen", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_MaximizeGadget)
If Window_Options
  ; Buttons erzeugen
	Window_Main_Buttons(4) = ButtonGadget(#PB_Any, 10, 10, 60, 30, "Button 4")
	Window_Main_Buttons(5) = ButtonGadget(#PB_Any, 80, 10, 60, 30, "Button 5")

	; Und die Eventprozeduren für Fensterevents zuordnen
  evh_SetWindowEvent(Window_Options, #PB_Event_ActivateWindow, @Window2Activate())
  evh_SetWindowEvent(Window_Options, #PB_Event_CloseWindow, @CloseMyWindow())

	; Hiermit werden die Buttons 4 und 5 zusammen bearbeitet
  evh_SetWindowEvent(Window_Options, #PB_Event_Gadget, @Window2Gadget())
EndIf

;*************************************************************************
;* Main code
;*************************************************************************

While evh_ProcessEvents(25, Window_Main, @OwnEventproc())
Wend

If IsWindow(Window_Options)
	evh_RemoveEvent(Window_Options)
	CloseWindow(Window_Options)
EndIf

If IsWindow(Window_Main)
	evh_RemoveEvent(Window_Main)
	CloseWindow(Window_Main)
EndIf

End
The resulting exe looks like this:
Image

Each event puts a new line to the Editorgadget.

Re: A smart Eventhandler Include for PB

Posted: Sat Jul 21, 2012 4:03 pm
by Zach
This looks pretty neat, thanks for sharing 8)

Re: A smart Eventhandler Include for PB

Posted: Sat Jul 21, 2012 5:38 pm
by Zebuddi123
Hi Thanks for sharing.

You can translate any commented lines in pb pbi files with a tool i have written http://www.purebasic.fr/english/viewtop ... 14&t=50324

it uses the same process ( Google translate ) its quick and easy to do.

Zebuddi :lol:

Re: A smart Eventhandler Include for PB

Posted: Sun Jul 22, 2012 12:55 pm
by Kurzer
Thank you for your comments. :D

Zebuddi123, I used your programm to translate the include and the description.
Unfortunately, the layout of the text was destroyed after the translation. Tabs were stripped and long lines "*****" were interupted by a space char "*** ***") . So I had to reedit the translation.

One question regarding your programm:
After the translation was finished the PureBasic editor was automatically started (by your programm I guess).
My Purebasic installtion is a portable installation and I have to start the editor all the time using the /PORTABLE parameter, otherwise the editor will generate a directory in the windows user path (and maybe create some registry-entries, don't know exactly the behavior of PB).

Which way the editor was startet by your program? I have not found any PB-entries in the user path, but I'm not really sure that the editor was started in portable mode.
Please, can you check the editorstart in your program and give me a short response?

For simplicity, I add the the translated eventhandler include in this post:

Code: Select all

;************************************************** ***********************
;*
;* Purebasic Eventhandler
;*
;************************************************** ***********************
;*
;* Program Name     : Purebasic Eventhandler
;* File name        : Eventhandler.pb
;* File Type        : Includefile [Main source, include file, data file]
;* Version          : 1.04
;* Date             : 06.07.2010
;* Author           : Markus Haacke (www.gismeth.de)
;* Programming lang.: PureBasic 4.50+
;* Compile as       : -
;* ------------------------------------------------- ----------------------
;* DESCRIPTION:
;*
;* See below
;*
;* ------------------------------------------------- ----------------------
;* History:
;* 1.04 - chg 06.07.2010:
;*                        All evh_SetXYZEvent () commands now contain the parameter iWindowNr
;*                        - Add new command evh_RemoveEvent () added
;*                        - Chg evh_Init () no longer has to be invoked manually
;* 1.03 - chg 03.07.2010:
;*                        Evh_EventArgsStruct extended iEventTimer
;* 1.02 - chg 28.05.2010:
;*                        Evh_ProcessEvents () has a new parameter: * stEvents
;* 1.01 - chg 26.05.2010:
;*                        The parameters of the event procedures changed to evh_EventArgsStruct
;* 1.00 - rel 23.05.2010:
;*                        Initial release
;*
;************************************************** ***********************

;************************************************** ***********************
;* Information on using
;************************************************** ***********************
; With this event handler of the evaluation window, button and menu events will be facilitated.
;
; After the GUI of the own program has been created, the gadgets, windows and
; Menu items are the following commands to its own event procedures associated with.
; 
; Use the following commands to the event handler is then added windows, gadgets and menu items:
; 
;   evh_SetWindowEvent (iWindowNr, iEventType, * Event Procedure)
;   evh_SetMenuEvent (iWindowNr, iMenuitemNr, * Event Procedure)
;   evh_SetGadgetEvent (iWindowNr, iGadgetNr, iEventType, * Event Procedure)
; 
; iWindowNr, iGadgetNr iMenuitemNr or jeopardizing the numbers of a specific window or gadgets
; Menu Item dar.
;
; iEventType describes the PB event to respond to the constant (eg # PB_EventType_LeftClick)
; The following event types can be used at the respective commands:
;
;   - Evh_SetWindowEvent (): All events, which are the Pure Basic Command WindowEvent () returns
;   - Evh_SetMenuEvent (): This event type is not indicated, it is only evaluated the number Menuitem
;   - Evh_SetGadgetEvent (): All events, which are the Pure Basic Command EventType () returns
;
; In * Event Procedure gives you the address of the handler to be invoked upon the occurrence of the event
; (It should be expressed using @ procedure name ()).
;
; Each event handler function is passed as the only parameter is a pointer to the following event structure parameters:
;
;   \ IEvent
;   \ IEventType
;   \ IEventWindow
;   \ IEventGadget
;   \ IEventMenu
;   \ IEventTimer
;   \ IEventwParam
;   \ IEventlParam
;
; (The structure type is "evh_EventArgsStruct" and is defined in event handler include)
;
; An event procedure is therefore always set up as follows (example):
;
;   Procedure Name (* stEventArgs.evh_EventArgsStruct)
;   ...
;   EndProcedure
;
; The fields of the structure corresponding to the equivalent commands WaitWindowEvent PB (), EventType ()
; Event Window (), etc., and contain just the result of this particular PB commands.
;
; The fields \ iEventGadget and contain \ iEventMenu only meaningful values ??if the field iEvent \ either
; # # Or PB_Event_Gadget PB_Event_Menu contains.
;
; IMPORTANT:
; Please do not forget the parameters (* stEventArgs.evh_EventArgsStruct) always in the Event Procedures
; installed, otherwise it will inevitably return to a fault! (=> The program crashes
; because the data were not collected from the stack)
; 
; To remove a registered event again, you call the evh_RemoveEvent () command on
;
;   evh_RemoveEvent (iWindowNr, [iItemNr], [iEventType])
;
; The two parameters and iItemNr iEventType correspond to the two parameters of the respective
; evh_SetXYZEvent command. So for example Gadget of the number and type of event at evh_SetGadgetEvent ()
; 
; If the two o.g. Parameter is omitted, and only given iWindowNr then be automatically
; ALL unregistered events, which include iWindowNr to the specified window.
; 
; This is useful when you close a window, all related, registered
; Events would like to unregister all at once.
;
; The actual event loop of the program is then limited to a two-line only construct.
; Example:
;
;   While evh_ProcessEvents (25, MainWindow, @ OwnEventproc (), 0)
;   Applicable
; 
; The command evh_ProcessEvents (iTimeOut, iObserveWindow, [OwnEventHandler *] [* stEvents]) takes the
; Event handler on his work. The command must be called within a loop always recurring
; are the same as the PB command WaitWindowEvent ().
;
; The parameters are as follows:
;
; iTimeOut: The parameter specifies the timeout value iTimeOut in milliseconds that the event handler
; should wait for a message. If at this time no message, then the program returns to the
; Loop back. The event handler uses the WaitWindowEvent () command, so far as analogy is what in
; PB help for this command is explained.
; (Note: If using the parameters * stEvents, then the value iTimeOut not relevant)
; 
; iObserveWindow: With iObserveWindow is one of the main window handle of his application.
; In this window, a # PB_Event_CloseWindow is triggered (= window is closed), then gives the
; Evh_ProcessEvents command () a # returns False. In all other cases, a # True.
; While the above is possible Dadruch / Wend event loop that is terminated by the return value # False.
; 
; * OwnEventHandler (optional): Since you can not possibly handle all events on the event handler
; want, you can specify a third parameter, the address of a separate event handler that * after *
; Processing of registered events is called addition. If you want to not have its own event processing
; procedure-use, then set it as the third parameter 0.
; 
; This gets its own event handling procedure as a parameter is also a pointer to an event
; Parameter structure passed by the type evh_EventArgsStruct:
;
;   \ IEvent
;   \ IEventType
;   \ IEventWindow
;   \ IEventGadget
;   \ IEventMenu
;   \ IEventTimer
;   \ IEventwParam
;   \ IEventlParam
; 
; Also the content of this field corresponds to the equivalent commands WaitWindowEvent PB (), EventType ()
; Event Window (), etc.
; 
; The body's own event-handling procedure is thus the same structure as an event procedure:
;
;   Procedure Name (* stEventArgs.evh_EventArgsStruct)
;   ...
;   EndProcedure
;
; IMPORTANT:
; Please do not forget the parameters (* stEventArgs.evh_EventArgsStruct) always in the event
; Incorporate processing procedure, otherwise it will inevitably return to a fault!
;
; * StEvents (optional): * stEvents a pointer is on an event-structure parameters dar.
; If this pointer =! 0 (ie it points to an initialized structure), then determines the
; Evh_ProcessEvents procedure () is not the PureBasic window events themselves, but the processed events,
; were passed through the * stEvents structure.
;
; This makes it possible to program its own event processing or even your own events,
; which are then automatically evaluated by the event handler (if previously registered events
; were.
;
; The structure pointed to by * stEvents evh_EventArgsStruct is also on the type and has the following structure:
;
;   \ IEvent
;   \ IEventType
;   \ IEventWindow
;   \ IEventGadget
;   \ IEventMenu
;   \ IEventTimer
;   \ IEventwParam
;   \ IEventlParam
;
; The parameters * and * stEvents OwnEventHandler not used, then it can be omitted.

;************************************************** ***********************
;* Prototypes, Constants, Variables & Structures
;************************************************** ***********************

; Constants for use in event management array
Enumeration 
	#EVH_Controltype_Gadget
	#EVH_Controltype_Menu
	#EVH_Controltype_Window
EndEnumeration

; Function variables for calling the event procedures
Prototype.i evh_CallEventProcedure(*stEventArgs)
Prototype.i evh_CallOwnEventHandler(*stEventArgs)

; Management structure for the event array
Structure evh_Eventstruct
	iWindowNr.i																										; Number of Windows to which the control belongs
	iControlType.i																								; EVH_Controltype_Gadget #, # EVH_Controltype_Menu, # EVH_Controltype_Window
	iControlNr.i																									; Number of gadgets / Menu Items / Windows
	iEventType.i																									; E.G. PB_EventType_LeftClick #, # PB_EventType_RightClick, etc. .. # PB_Event_SizeWindow
	iEventProcedure.i																							; Address of the procedure to
EndStructure

; Structure for internal management
Structure evh_Settingsstruct
	iHandlerInitialized.i																					; Indicates whether the event handler has been initialized correctly
	iCurrentEntry.i																								; Index pointer to current entry in the array (always the last valid entry)
EndStructure

; Structure for the parameters passed to the event procedures
Structure evh_EventArgsStruct																		; Parameter structure that the event handlers is transferred by means of pointers.
	iEvent.i
	iEventType.i
	iEventWindow.i
	iEventGadget.i
	iEventMenu.i
	iEventTimer.i
	iEventwParam.i
	iEventlParam.i
EndStructure

Global evh_stSettings.evh_Settingsstruct

;************************************************** ***********************
;* Procedures
;************************************************** ***********************
Procedure 	evh_Init()
	; + ------------------------------------------------- ----------------
	; | Description: Initializes the variables of the event handler, if not done
	; |: The procedure is called internally only!
	; | Arguments  : -
	; | Results		 : -
	; + ------------------------------------------------- ----------------
	
	If Not evh_stSettings\iHandlerInitialized
		Global Dim evh_stEventArray.evh_Eventstruct(0)
		evh_stSettings\iHandlerInitialized = #True
	EndIf

EndProcedure
Procedure.i evh_SetWindowEvent(iWindowNr.i, iEventType.i, *EventProcedure)
	; + ------------------------------------------------- ----------------
	; | Description: Assigns an event handler to a window
	; | Arguments  : iWindowNr        : number of window
	; |						 : IEventType       : Event type constant, will be responding to the
	; |						 : * Event Procedure: pointer to the procedure to be called when this event type
	; | Results    : False # if it has been evh_Init () not previously called, otherwise # True
	; + ------------------------------------------------- ----------------
	Protected iCount.i

	evh_Init()
	
	; If the event is already registered, then assign the new event handler ...
	For iCount = 0 To evh_stSettings\iCurrentEntry - 1
		If evh_stEventArray(iCount)\iControlNr = iWindowNr And evh_stEventArray(iCount)\iEventType = iEventType
			evh_stEventArray(iCount)\iEventProcedure = *EventProcedure
			ProcedureReturn #True
		EndIf
	Next iCount

	; ... otherwise the event register
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iWindowNr = iWindowNr
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iControlType = #EVH_Controltype_Window
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iControlNr = iWindowNr
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iEventType = iEventType
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iEventProcedure = *EventProcedure
	evh_stSettings\iCurrentEntry + 1
	ReDim evh_stEventArray.evh_Eventstruct(evh_stSettings\iCurrentEntry)

	ProcedureReturn #True
EndProcedure
Procedure.i evh_SetGadgetEvent(iWindowNr.i, iGadgetNr.i, iEventType.i, *EventProcedure)
	; + ------------------------------------------------- ----------------
	; | Description: Assigns an event handler for a gadget
	; | Arguments	 : iWindowNr				: number of window
	; |						 : IGadgetNr				: number of gadgets
	; |						 : IEventType			  : Event type constant, will be responding to the
	; |						 : * Event Procedure: pointer to the procedure to be called when this event type
	; | Results		 : False # if it has been evh_Init () not previously called, otherwise # True
	; + ------------------------------------------------- ----------------
	Protected iCount.i

	evh_Init()

	; If the event is already registered, then assign the new event handler ...
	For iCount = 0 To evh_stSettings\iCurrentEntry - 1
		If evh_stEventArray(iCount)\iControlNr = iGadgetNr And evh_stEventArray(iCount)\iEventType = iEventType
			evh_stEventArray(iCount)\iEventProcedure = *EventProcedure
			ProcedureReturn #True
		EndIf
	Next iCount

	; ... otherwise the event register
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iWindowNr = iWindowNr
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iControlType = #EVH_Controltype_Gadget
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iControlNr = iGadgetNr
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iEventType = iEventType
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iEventProcedure = *EventProcedure
	evh_stSettings\iCurrentEntry + 1
	ReDim evh_stEventArray.evh_Eventstruct(evh_stSettings\iCurrentEntry)

	ProcedureReturn #True
EndProcedure
Procedure.i evh_SetMenuEvent  (iWindowNr.i, iMenuitemNr.i, *EventProcedure)
	; + ------------------------------------------------- ----------------
	; | Description: Assigns an event handler to Menüitem
	; | Arguments	 : iWindowNr: Number of the window is one of the menu
	; |						 : IMenuitemNr: Number of Menu Items
	; |						 : * Event Procedure: pointer to the procedure to be called when this event type
	; | Results		 : False # if it has been evh_Init () not previously called, otherwise # True
	; + ------------------------------------------------- ----------------
	Protected iCount.i

	evh_Init()

	; If the event is already registered, then assign the new event handler ...
	For iCount = 0 To evh_stSettings\iCurrentEntry - 1
		If evh_stEventArray(iCount)\iControlNr = iMenuitemNr And evh_stEventArray(iCount)\iWindowNr = iWindowNr
			evh_stEventArray(iCount)\iEventProcedure = *EventProcedure
			ProcedureReturn #True
		EndIf
	Next iCount

	; ... otherwise the event register
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iWindowNr = iWindowNr
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iControlType = #EVH_Controltype_Menu
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iControlNr = iMenuitemNr
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iEventType = 0
	evh_stEventArray(evh_stSettings\iCurrentEntry)\iEventProcedure = *EventProcedure
	evh_stSettings\iCurrentEntry + 1
	ReDim evh_stEventArray.evh_Eventstruct(evh_stSettings\iCurrentEntry)

	ProcedureReturn #True
EndProcedure
;-
Procedure.i evh_RemoveEvent(iWindowNr.i, iItemNr.i = -1, iEventType.i = -1)
	; + ------------------------------------------------- ----------------
	; | Description: Removes a registered event of a gadget entry
	; | Arguments	 : iWindowNr : Number of the window is one of the event
	; | 					 :					 : Are the following two parameters are = 0, then all
	; | 					 :					 : Remove events that were recorded for this window.
	; |						 : IItemNr	 : number of gadgets, menuitems, or Windows
	; |						 : IEventType: Event type constant that was previously registered (if MenuEvents = 0)
	; | Results		 : # False if evh_Init () has not been called or the
	; |						 : Event was not previously registered, otherwise # True
	; + ------------------------------------------------- ----------------
	Protected iCount.i, iEventsRemoved.i, iAllEventsFromWindow.i = #False
	Protected iExitcode.i = #False

	evh_Init()
	
	; If you pass only iWindowNr, then delete all events from this window
	If iItemNr = -1 And iEventType = -1
		iAllEventsFromWindow = #True
	EndIf
	
	; Registered user (s) Search for an event (s) in the list
	For iCount = 0 To evh_stSettings\iCurrentEntry - 1
		If (iAllEventsFromWindow = #False And evh_stEventArray(iCount)\iWindowNr = iWindowNr And evh_stEventArray(iCount)\iControlNr = iItemNr And evh_stEventArray(iCount)\iEventType = iEventType) Or (iAllEventsFromWindow = #True And evh_stEventArray(iCount)\iWindowNr = iWindowNr)
			; Entry with the next to last entry in the array swap (the last are all zeros)
			evh_stEventArray(iCount)\iWindowNr       = evh_stEventArray(evh_stSettings\iCurrentEntry - 1)\iWindowNr
			evh_stEventArray(iCount)\iControlNr      = evh_stEventArray(evh_stSettings\iCurrentEntry - 1)\iControlNr
			evh_stEventArray(iCount)\iControlType    = evh_stEventArray(evh_stSettings\iCurrentEntry - 1)\iControlType
			evh_stEventArray(iCount)\iEventType      = evh_stEventArray(evh_stSettings\iCurrentEntry - 1)\iEventType
			evh_stEventArray(iCount)\iEventProcedure = evh_stEventArray(evh_stSettings\iCurrentEntry - 1)\iEventProcedure
			iEventsRemoved + 1
			iExitcode = #True
		EndIf
	Next iCount
	
	; and reduce the array
			evh_stSettings\iCurrentEntry - iEventsRemoved
	ReDim evh_stEventArray.evh_Eventstruct(evh_stSettings\iCurrentEntry)
	
	ProcedureReturn iExitcode
EndProcedure
;-
Procedure.i evh_ProcessEvents(iTimeOut.i, iObserveWindow.i, *OwnEventHandler = 0, *stEvents.evh_EventArgsStruct = 0)
	; + ------------------------------------------------- ----------------
	; | Description: Gets the event handler of the gadget on, if it was previously registered
	; |: Calls offered optionally on a separate event routine
	; | Arguments	 : iTimeOut: Parameters for WaitWindowEvent
	; |						 : IObserveWindow		: Number of the window whose events you want to monitor # PB_Event_CloseWindow
	; |						 : 							 		: Occurs # PB_Event_CloseWindow for this window, the procedure returns False #
	; |						 : * OwnEventHandler: pointer to an optional event-handling procedure
	; |						 :									: The event handler receives a pointer as a parameter passed to a evh_EventArgsStruct
	; |						 : * StEvents			  : pass a pointer to an optional event structure with which to edit events
	; |						 :									: Is stEvents initialized, then evh_ProcessEvents () the events determined not itself
	; |						 :								  : It accesses the events of the structure. Is the structure pointer = 0, then the
	; |						 :									: PureBasic events themselves determined.
	; | Results		 : # False occurred when # PB_Event_CloseWindow for the monitored window is otherwise # True
	; + ------------------------------------------------- ----------------
	Protected iCount.i
	Protected evh_stEventArgs.evh_EventArgsStruct
	Protected evh_CallEventProcedure.evh_CallEventProcedure
	Protected evh_CallOwnEventHandler.evh_CallOwnEventHandler

	If *stEvents <> 0 
	  evh_stEventArgs\iEvent       = *stEvents\iEvent
	  evh_stEventArgs\iEventType   = *stEvents\iEventType
	  evh_stEventArgs\iEventWindow = *stEvents\iEventWindow
	  evh_stEventArgs\iEventGadget = *stEvents\iEventGadget
	  evh_stEventArgs\iEventMenu   = *stEvents\iEventMenu
	  evh_stEventArgs\iEventTimer  = *stEvents\iEventTimer
	  evh_stEventArgs\iEventwParam = *stEvents\iEventwParam
	  evh_stEventArgs\iEventlParam = *stEvents\iEventlParam
	Else
	  evh_stEventArgs\iEvent       = WaitWindowEvent(iTimeOut)
	  evh_stEventArgs\iEventType   = EventType()
	  evh_stEventArgs\iEventWindow = EventWindow()
	  evh_stEventArgs\iEventGadget = EventGadget()
	  evh_stEventArgs\iEventMenu   = EventMenu()
	  evh_stEventArgs\iEventTimer  = EventTimer()
	  evh_stEventArgs\iEventwParam = EventwParam()
	  evh_stEventArgs\iEventlParam = EventlParam()
	EndIf

	; Check if an event has occurred for a previously registered gadget / Menüitem
	If evh_stSettings\iCurrentEntry > 0 And evh_stSettings\iHandlerInitialized And evh_stEventArgs\iEvent > 0
		For iCount = 0 To evh_stSettings\iCurrentEntry - 1

			; Check WindowEvents
			If evh_stEventArray(iCount)\iControlType = #EVH_Controltype_Window
				If evh_stEventArray(iCount)\iControlNr = evh_stEventArgs\iEventWindow And evh_stEventArray(iCount)\iEventType = evh_stEventArgs\iEvent
					evh_CallEventProcedure = evh_stEventArray(iCount)\iEventProcedure
					evh_CallEventProcedure(@evh_stEventArgs)
				EndIf
			EndIf

			; Events Gadget review
			If evh_stEventArgs\iEvent = #PB_Event_Gadget And evh_stEventArray(iCount)\iControlType = #EVH_Controltype_Gadget
				If evh_stEventArray(iCount)\iWindowNr = evh_stEventArgs\iEventWindow And evh_stEventArray(iCount)\iControlNr = evh_stEventArgs\iEventGadget And evh_stEventArray(iCount)\iEventType = evh_stEventArgs\iEventType
					evh_CallEventProcedure = evh_stEventArray(iCount)\iEventProcedure
					evh_CallEventProcedure(@evh_stEventArgs)
				EndIf
			EndIf

			; Events Menu Check
			If evh_stEventArgs\iEvent = #PB_Event_Menu And evh_stEventArray(iCount)\iControlType = #EVH_Controltype_Menu
				If evh_stEventArray(iCount)\iWindowNr = evh_stEventArgs\iEventWindow And evh_stEventArray(iCount)\iControlNr = evh_stEventArgs\iEventMenu
					evh_CallEventProcedure = evh_stEventArray(iCount)\iEventProcedure
					evh_CallEventProcedure(@evh_stEventArgs)
				EndIf
			EndIf

		Next iCount
	EndIf

	; The optional, separate event routines call
	If *OwnEventHandler > 0
		evh_CallOwnEventHandler = *OwnEventHandler
		evh_CallOwnEventHandler(@evh_stEventArgs)
	EndIf
	
	; Check that the window to be monitored has been closed
	If evh_stEventArgs\iEvent = #PB_Event_CloseWindow And evh_stEventArgs\iEventWindow = iObserveWindow 
		ProcedureReturn #False
	Else
		ProcedureReturn #True
	EndIf

EndProcedure

Re: A smart Eventhandler Include for PB

Posted: Sun Jul 22, 2012 2:42 pm
by Zebuddi123
Hi kurzer

The PBIDE is called after the translation via RunProgram() command, no registry keys used. it also creates a backup of the original file with the original filename and with extension .backup just in case it screws the translation up, it`s just a case of delete the newly created file and remove .backup extension from the original file, more work needs doing on the program needs unicode mode also have used Trim() for removal of whitespaces @ beginning & eos, the version you have used only translates anything after the ; comment char so should not disturb any program flow.

I have moved further on with this dealing with translation of anything in quotes (working good) alas i have to now incorporate an exemption list of quoted stuff not to alter ie "c:\" absolute strings.

if you use it further and find probs bugs etc i would appreciate feedback to improve the programs capabilities.


Zebuddi. :D

Re: A smart Eventhandler Include for PB

Posted: Sun Jul 22, 2012 3:02 pm
by Kurzer
Zebuddi123 wrote:The PBIDE is called after the translation via RunProgram() command, no registry keys used.
Ok, to go for sure:
You don't call 'PureBasic.exe /PORTABLE' ??? You call 'PureBasic.exe' via RunProgramm()?

If you call the exe without the /PORTABLE option It infiltrate my portable Installation I guess.
In my opinion PureBasic writes some data within the 'aplication data' folder or at any other place in the user path if I do not start it with the /PORTABLE parameter.

So I am all the time just carefull to start PureBasic editor with the /PORTABLE option.

Is there anybody out there who knows in which folder the PB editor writes data (prefs and so on) if it was not startet with the /PORTABLE parameter? I'm a bit paranoid regarding a clean and transparent system.
I better had to start Zebuddi123s programm in a virtual machine.

Re: A smart Eventhandler Include for PB

Posted: Sun Jul 22, 2012 3:31 pm
by Zebuddi123
Try here: C:\Users\"your user name here"\AppData\Roaming\PureBasic\

it uses RunProgram("path\filename.pb")

could you explain the meaning of "I better had to start Zebuddi123s programm in a virtual machine." ????

Zebuddi. :shock:

Re: A smart Eventhandler Include for PB

Posted: Sun Jul 22, 2012 3:56 pm
by Kurzer
Zebuddi123 wrote:Could you explain the meaning of "I better had to start Zebuddi123s programm in a virtual machine." ????
It is not meant personally. I'm a bit paranoid and want to have a clean system.
Running your programm in a virtual machine would leave my system untouchted. So I must not have paranoia about changes in my registry, system folders and so on.

But I can see... "it uses RunProgram("path\filename.pb")" that you do not start the PureBasic.exe directly. :shock:

That shows me, that my reputed 'clean system' or my 'portable' PB installation ist not so portable like I thought.
It seems sometime in the past, I started the PureBasic.exe (or one of the six parallel PB-installations) manually and without the /PORTABLE parameter. So PB has registered the .pb and .pbi extensions in the windows registry. Otherwise the PB editor would not be launched by the command RunProgram("path\filename.pb").

So your program even showed me that my system is not set up correctly.
Everything is OK. Thanks for that. :D

Re: A smart Eventhandler Include for PB

Posted: Sat Jul 28, 2012 5:43 pm
by Zach
Kurzer, a VM seems a bit drastic for running a program to keep your Registry and filesystem "clean", don't you think?

Have you heard of Sandboxie? It basically affords the same protection, but runs in a Sandbox, as opposed to a resource hogging VM.

http://www.sandboxie.com/

Re: A smart Eventhandler Include for PB

Posted: Mon Jul 30, 2012 12:10 pm
by Kurzer
Hello Zach,

thank you for your comment and the Sandboxie link. I didn't know sandboxie before.

But I have to clarify something. ;-)
I don't use the VM each time when I run an 'evil' program.

I use the VM to investigate a new program. Making snapshots of the filesystem and registry and compares it to know where the changes are. If the program is clean, then I install it in my real environment without any VM-stuff.

Of course, I also install non-portable programms in my real environment if I need them, but I would like to know in advance at which places the program writes its data.

I hope I was able to straighten your impression of the "hyper-paranoid" user kurzer ;-)

Re: A smart Eventhandler Include for PB

Posted: Tue Jul 31, 2012 12:25 pm
by Zach
That's cool. I had a good idea of what you were doing and why.

Sandboxie might help you better with some of that too, I think.. i.e if a program drops its own files onto the system, they should be relatively easy to find in the sandboxed filesystem