Event Handler

Tight_Coder_Ex 0 Tallied Votes 208 Views Share

I prefer to use this method as it doesn't clutter a windows procedure with dozens of conditionals and it address my primary objective of coding as tight as possible [28 bytes]. If you think my method can be improved upon in size and/or speed please post your solution.

Note: I have not tested this algorithym yet

; 				      *** MESSAGE HANDLER ***

; This procedure determines if application has a handler for a particular event.  All windows
; procedures are passed to this subroutine except those that have been sub or super classed.

;	ENTRY:	ESI = Pointer to message map
;		ECX = Number of sets in map.

; Each set consists of a 16 bit ID and 32 bit pointer to proceedure.

;	LEAVE:	EAX = 0 if application handled event, or result of DefWindowProc is not.
; ____________________________________________________________________________________________		

  ; 		ESP +  0 = Return address in kernel module
  ;		ESP +  4 = hWnd,	this windows 32 bit handle
  ;		ESP +  8 = Msg,	Message ID passed by OS.
  ;		ESP + 12 = wParam
  ;		ESP + 16 = lParam

  MsgHandler		mov	edx, [esp + 8]	; Get message ID 0 - 1024 or user defined.

	; In the unlikely event a null map is passed to this routine, this method of
	; testing ECX first will prevent a fatal crash.

  .NextMsg		and	ecx, ecx	; Are we at the end yet
			jz	.Default	; ZR = 1, If we are to do default proceesing.

			dec	ecx		; Decrement counter
			lodsw			; Get 16 bit ID from message map
			cmp	 ax, dx		; Is there a match
			lodsd			; Load pointer
			jnz	.NextMsg

  	; At this point we've found a match and as many events need wParam & lParam,
	; I'm going to establish a pointer to those in EBX.  hWnd can be simply addressed
	; by EBX - 8 or lParam by EBX + 4.

			lea	ebx, [esp + 12]	; EBX points to wParam
			call	eax		; Execute event
			jnc	.Default	; CY = 0, if event requires default proc.
                                      xor         eax,  eax             ; Handled must return 0
			ret	16		; Stack needs to be re-aligned.

  	; As hWnd, Msg, wParam & lParam are already on the stack I use this method
	; as a trace into kernel showed OS handles this appropriately and there is no
	; point pushing onto stack what is already there.  I've tested this on 98/ME/XP.

  .Default		pop	ebx
			call	_DefWindowProcA@16
			jmp	ebx

  ; You'll notice at this point we don't need RET 16 as the call to DefWindowProc has already
  ; done that for us.