Mega Code Archive

 
Categories / Delphi / Examples
 

Windowsmessagetrap

unit SREUnit; {© Richard Ebbs 1998} {Module: SEARCH} {'Results' Unit of SEARCH RESULTS module for WRITER'S TOOLKIT package...} interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, IniFiles; type WParameter = LongInt; LParameter = LongInt; type TResultsForm = class(TForm) {stuff...} procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private {private declarations} public {public declarations} end; var ResultsForm: TResultsForm; implementation {$R *.DFM} var {declare a variable to point to the window procedure we plan to replace...} OldREWindProc : Pointer; {code below cleverly traps scroll messages for the RichEdit by 'replacing' normal Windows code with a function of our own. Other tricks we use to ensure that the Memo scrolls in synch with the RichEdit include instantly returning focus to the RichEdit if the user tries to put the cursor in the Memo (which is equivalent to disabling the Memo without dimming the text) and also we set the KeyPreview property of the enclosing form to True which allows us to trap keypress messages at the form level before they filter down to objects below. Note that we don't include function headers (declarations for these procedures within the class declaration above...} function NewREWindProc(WindowHandle: hWnd; TheMessage: WParameter; ParamW: WParameter; ParamL: LParameter): LongInt stdcall; begin {intercept 'scroll' messages pertaining to our Memo on the right, so that we can mirror all scrolling in our Memo on the left...} if TheMessage = WM_VSCROLL then begin {when CallWindowProc, below, handles a WM_VSCROLL message EXTRA information on the message will be held in ParamW and ParamL, so we just use them as is in our SendMessage procedure without bothering, or needing, to know exactly what they are doing...} SendMessage(ResultsForm.MInfoMemo.Handle, WM_VSCROLL, ParamW, ParamL); end; {Call the old Window function to allow processing of the message...} NewREWindProc := CallWindowProc(OldREWindProc, WindowHandle, TheMessage, ParamW, ParamL); end; procedure TResultsForm.FormCreate(Sender: TObject); var badFNameChars: TpossFNameChars; begin {specify a new function to handle the RichEdit's messages and store a pointer to the old function. SetWindowLong is an API function. Here, when we call SetWindowLong, because the second parameter is GWL_WNDPROC we can then supply the address of a 'replacement' function, in this case the NewREWindProc function, which we can then use to trap all Windows messages pertaining to RichEdit...} OldREWindProc := Pointer(SetWindowLong(ResultsForm.LinesMemo.Handle,GWL_WNDPROC, LongInt(@NewREWindProc))); {take this opportunity to define a SET of valid fileName characters...} badFNameChars := ['\','/',':','*','?','"','<','>','|']; validFNameChars := ['!'..'~']; validFNameChars := validFNameChars - badFNameChars; prevLoadFile := 0; currLoadFile := 0; ReadINIFile; end; procedure TResultsForm.FormDestroy(Sender: TObject); {set the message-trapping function back to it's original version...} begin SetWindowLong(ResultsForm.LinesMemo.Handle, GWL_WNDPROC, LongInt(OldREWindProc)); end; procedure TResultsForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); {work around the fact that attempting to trap uparrow and downarrow key messages in the NewREWindProc function creates problems and take advantage of the fact that by setting the KeyPreview property of the enclosing form to True, we set things up so that keypress messages for keypresses occuring within any object on the form are then processed HERE before being sent to the objects themselves. This enables us to trap undesirable keypresses, -and, since we can handle both PageUp and PageDown keypress messages no problem in NewREWindProc (and since they are the only keypresses we want to handle) all we do here is to convert every other keypress to ESC, which in this context DOES NOTHING AT ALL...} const PAGEUP = 33; PAGEDOWN = 34; begin if not((Key = PAGEUP) or (Key = PAGEDOWN)) then begin Key := VK_ESCAPE; end; end;