mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 17:36:00 +00:00
801 lines
26 KiB
ObjectPascal
801 lines
26 KiB
ObjectPascal
{******************************************************************************}
|
|
{ }
|
|
{ Hooking mechanism to receive system events interface Unit for Object Pascal }
|
|
{ }
|
|
{ Portions created by Microsoft are Copyright (C) 1995-2001 Microsoft }
|
|
{ Corporation. All Rights Reserved. }
|
|
{ }
|
|
{ The original file is: winable.h, released June 2000. The original Pascal }
|
|
{ code is: WinAble.pas, released December 2000. The initial developer of the }
|
|
{ Pascal code is Marcel van Brakel (brakelm att chello dott nl). }
|
|
{ }
|
|
{ Portions created by Marcel van Brakel are Copyright (C) 1999-2001 }
|
|
{ Marcel van Brakel. All Rights Reserved. }
|
|
{ }
|
|
{ Obtained through: Joint Endeavour of Delphi Innovators (Project JEDI) }
|
|
{ }
|
|
{ You may retrieve the latest version of this file at the Project JEDI }
|
|
{ APILIB home page, located at http://jedi-apilib.sourceforge.net }
|
|
{ }
|
|
{ The contents of this file are used with permission, subject to the Mozilla }
|
|
{ Public License Version 1.1 (the "License"); you may not use this file except }
|
|
{ in compliance with the License. You may obtain a copy of the License at }
|
|
{ http://www.mozilla.org/MPL/MPL-1.1.html }
|
|
{ }
|
|
{ Software distributed under the License is distributed on an "AS IS" basis, }
|
|
{ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for }
|
|
{ the specific language governing rights and limitations under the License. }
|
|
{ }
|
|
{ Alternatively, the contents of this file may be used under the terms of the }
|
|
{ GNU Lesser General Public License (the "LGPL License"), in which case the }
|
|
{ provisions of the LGPL License are applicable instead of those above. }
|
|
{ If you wish to allow use of your version of this file only under the terms }
|
|
{ of the LGPL License and not to allow others to use your version of this file }
|
|
{ under the MPL, indicate your decision by deleting the provisions above and }
|
|
{ replace them with the notice and other provisions required by the LGPL }
|
|
{ License. If you do not delete the provisions above, a recipient may use }
|
|
{ your version of this file under either the MPL or the LGPL License. }
|
|
{ }
|
|
{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
|
|
{ }
|
|
{******************************************************************************}
|
|
|
|
// $Id: JwaWinAble.pas,v 1.11 2007/09/14 06:48:47 marquardt Exp $
|
|
|
|
{$IFNDEF JWA_OMIT_SECTIONS}
|
|
unit JwaWinAble;
|
|
|
|
{$WEAKPACKAGEUNIT}
|
|
{$ENDIF JWA_OMIT_SECTIONS}
|
|
|
|
{$HPPEMIT ''}
|
|
{$HPPEMIT '#include "WinAble.h"'}
|
|
{$HPPEMIT ''}
|
|
|
|
{$IFNDEF JWA_OMIT_SECTIONS}
|
|
{$I ..\Includes\JediAPILib.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
JwaWinType;
|
|
{$ENDIF JWA_OMIT_SECTIONS}
|
|
|
|
|
|
|
|
{$IFNDEF JWA_IMPLEMENTATIONSECTION}
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
//
|
|
// This gets GUI information out of context. If you pass in a NULL thread ID,
|
|
// we will get the 'global' information, using the foreground thread. This
|
|
// is guaranteed to be the real active window, focus window, etc. Yes, you
|
|
// could do it yourself by calling GetForegorundWindow, getting the thread ID
|
|
// of that window via GetWindowThreadProcessId, then passing the ID into
|
|
// GetGUIThreadInfo(). However, that takes three calls and aside from being
|
|
// a pain, anything could happen in the middle. So passing in NULL gets
|
|
// you stuff in one call and hence also works right.
|
|
//
|
|
|
|
type
|
|
LPGUITHREADINFO = ^GUITHREADINFO;
|
|
{$EXTERNALSYM LPGUITHREADINFO}
|
|
tagGUITHREADINFO = record
|
|
cbSize: DWORD;
|
|
flags: DWORD;
|
|
hwndActive: HWND;
|
|
hwndFocus: HWND;
|
|
hwndCapture: HWND;
|
|
hwndMenuOwner: HWND;
|
|
hwndMoveSize: HWND;
|
|
hwndCaret: HWND;
|
|
rcCaret: RECT;
|
|
end;
|
|
{$EXTERNALSYM tagGUITHREADINFO}
|
|
GUITHREADINFO = tagGUITHREADINFO;
|
|
{$EXTERNALSYM GUITHREADINFO}
|
|
TGuiThreadInfo = GUITHREADINFO;
|
|
PGuiThreadInfo = LPGUITHREADINFO;
|
|
|
|
const
|
|
GUI_CARETBLINKING = $00000001;
|
|
{$EXTERNALSYM GUI_CARETBLINKING}
|
|
GUI_INMOVESIZE = $00000002;
|
|
{$EXTERNALSYM GUI_INMOVESIZE}
|
|
GUI_INMENUMODE = $00000004;
|
|
{$EXTERNALSYM GUI_INMENUMODE}
|
|
GUI_SYSTEMMENUMODE = $00000008;
|
|
{$EXTERNALSYM GUI_SYSTEMMENUMODE}
|
|
GUI_POPUPMENUMODE = $00000010;
|
|
{$EXTERNALSYM GUI_POPUPMENUMODE}
|
|
|
|
|
|
function GetGUIThreadInfo(idThread: DWORD; var lpgui: GUITHREADINFO): BOOL; stdcall;
|
|
{$EXTERNALSYM GetGUIThreadInfo}
|
|
|
|
function GetWindowModuleFileNameW(hwnd: HWND; lpFileName: LPWSTR; cchFileName: UINT): UINT; stdcall;
|
|
{$EXTERNALSYM GetWindowModuleFileNameW}
|
|
function GetWindowModuleFileNameA(hwnd: HWND; lpFileName: LPSTR; cchFileName: UINT): UINT; stdcall;
|
|
{$EXTERNALSYM GetWindowModuleFileNameA}
|
|
function GetWindowModuleFileName(hwnd: HWND; lpFileName: LPTSTR; cchFileName: UINT): UINT; stdcall;
|
|
{$EXTERNALSYM GetWindowModuleFileName}
|
|
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
//
|
|
// This returns FALSE if the caller doesn't have permissions to do this
|
|
// esp. if someone else is dorking with input. I.E., if some other thread
|
|
// disabled input, and thread 2 tries to diable/enable it, the call will
|
|
// fail since thread 1 has the cookie.
|
|
//
|
|
|
|
function BlockInput(fBlockIt: BOOL): BOOL; stdcall;
|
|
{$EXTERNALSYM BlockInput}
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
//
|
|
// Note that the dwFlags field uses the same flags as keybd_event and
|
|
// mouse_event, depending on what type of input this is.
|
|
//
|
|
|
|
type
|
|
LPMOUSEINPUT = ^MOUSEINPUT;
|
|
{$EXTERNALSYM LPMOUSEINPUT}
|
|
PMOUSEINPUT = ^MOUSEINPUT;
|
|
{$EXTERNALSYM PMOUSEINPUT}
|
|
tagMOUSEINPUT = record
|
|
dx: LONG;
|
|
dy: LONG;
|
|
mouseData: DWORD;
|
|
dwFlags: DWORD;
|
|
time: DWORD;
|
|
dwExtraInfo: DWORD;
|
|
end;
|
|
{$EXTERNALSYM tagMOUSEINPUT}
|
|
MOUSEINPUT = tagMOUSEINPUT;
|
|
{$EXTERNALSYM MOUSEINPUT}
|
|
TMouseInput = MOUSEINPUT;
|
|
|
|
LPKEYBDINPUT = ^KEYBDINPUT;
|
|
{$EXTERNALSYM LPKEYBDINPUT}
|
|
PKEYBDINPUT = ^KEYBDINPUT;
|
|
{$EXTERNALSYM PKEYBDINPUT}
|
|
tagKEYBDINPUT = record
|
|
wVk: WORD;
|
|
wScan: WORD;
|
|
dwFlags: DWORD;
|
|
time: DWORD;
|
|
dwExtraInfo: DWORD;
|
|
end;
|
|
{$EXTERNALSYM tagKEYBDINPUT}
|
|
KEYBDINPUT = tagKEYBDINPUT;
|
|
{$EXTERNALSYM KEYBDINPUT}
|
|
TKeybdInput = KEYBDINPUT;
|
|
|
|
LPHARDWAREINPUT = ^HARDWAREINPUT;
|
|
{$EXTERNALSYM LPHARDWAREINPUT}
|
|
PHARDWAREINPUT = ^HARDWAREINPUT;
|
|
{$EXTERNALSYM PHARDWAREINPUT}
|
|
tagHARDWAREINPUT = record
|
|
uMsg: DWORD;
|
|
wParamL: WORD;
|
|
wParamH: WORD;
|
|
dwExtraInfo: DWORD;
|
|
end;
|
|
{$EXTERNALSYM tagHARDWAREINPUT}
|
|
HARDWAREINPUT = tagHARDWAREINPUT;
|
|
{$EXTERNALSYM HARDWAREINPUT}
|
|
THardwareInput = HARDWAREINPUT;
|
|
|
|
const
|
|
INPUT_MOUSE = 0;
|
|
{$EXTERNALSYM INPUT_MOUSE}
|
|
INPUT_KEYBOARD = 1;
|
|
{$EXTERNALSYM INPUT_KEYBOARD}
|
|
INPUT_HARDWARE = 2;
|
|
{$EXTERNALSYM INPUT_HARDWARE}
|
|
|
|
type
|
|
LPINPUT = ^INPUT;
|
|
{$EXTERNALSYM LPINPUT}
|
|
PINPUT = ^INPUT;
|
|
{$EXTERNALSYM PINPUT}
|
|
tagINPUT = record
|
|
type_: DWORD;
|
|
case Integer of
|
|
0: (mi: MOUSEINPUT);
|
|
1: (ki: KEYBDINPUT);
|
|
2: (hi: HARDWAREINPUT);
|
|
end;
|
|
{$EXTERNALSYM tagINPUT}
|
|
INPUT = tagINPUT;
|
|
{$EXTERNALSYM INPUT}
|
|
TInput = INPUT;
|
|
|
|
//
|
|
// This returns the number of inputs played back. It will disable input
|
|
// first, play back as many as possible, then reenable input. In the middle
|
|
// it will pulse the RIT to make sure that the fixed input queue doesn't
|
|
// fill up.
|
|
//
|
|
|
|
function SendInput(cInputs: UINT; pInputs: LPINPUT; cbSize: Integer): UINT; stdcall;
|
|
{$EXTERNALSYM SendInput}
|
|
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
const
|
|
CCHILDREN_FRAME = 7;
|
|
{$EXTERNALSYM CCHILDREN_FRAME}
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
//
|
|
// This generates a notification that anyone watching for it will get.
|
|
// This call is superfast if nobody is hooking anything.
|
|
//
|
|
|
|
procedure NotifyWinEvent(event: DWORD; hwnd: HWND; idObject, idChild: LONG); stdcall;
|
|
{$EXTERNALSYM NotifyWinEvent}
|
|
|
|
//
|
|
// hwnd + idObject can be used with OLEACC.DLL's OleGetObjectFromWindow()
|
|
// to get an interface pointer to the container. indexChild is the item
|
|
// within the container in question. Setup a VARIANT with vt VT_I4 and
|
|
// lVal the indexChild and pass that in to all methods. Then you
|
|
// are raring to go.
|
|
//
|
|
|
|
//
|
|
// Common object IDs (cookies, only for sending WM_GETOBJECT to get at the
|
|
// thing in question). Positive IDs are reserved for apps (app specific),
|
|
// negative IDs are system things and are global, 0 means "just little old
|
|
// me".
|
|
//
|
|
|
|
const
|
|
CHILDID_SELF = 0;
|
|
{$EXTERNALSYM CHILDID_SELF}
|
|
|
|
// Reserved IDs for system objects
|
|
|
|
OBJID_WINDOW = DWORD($00000000);
|
|
{$EXTERNALSYM OBJID_WINDOW}
|
|
OBJID_SYSMENU = DWORD($FFFFFFFF);
|
|
{$EXTERNALSYM OBJID_SYSMENU}
|
|
OBJID_TITLEBAR = DWORD($FFFFFFFE);
|
|
{$EXTERNALSYM OBJID_TITLEBAR}
|
|
OBJID_MENU = DWORD($FFFFFFFD);
|
|
{$EXTERNALSYM OBJID_MENU}
|
|
OBJID_CLIENT = DWORD($FFFFFFFC);
|
|
{$EXTERNALSYM OBJID_CLIENT}
|
|
OBJID_VSCROLL = DWORD($FFFFFFFB);
|
|
{$EXTERNALSYM OBJID_VSCROLL}
|
|
OBJID_HSCROLL = DWORD($FFFFFFFA);
|
|
{$EXTERNALSYM OBJID_HSCROLL}
|
|
OBJID_SIZEGRIP = DWORD($FFFFFFF9);
|
|
{$EXTERNALSYM OBJID_SIZEGRIP}
|
|
OBJID_CARET = DWORD($FFFFFFF8);
|
|
{$EXTERNALSYM OBJID_CARET}
|
|
OBJID_CURSOR = DWORD($FFFFFFF7);
|
|
{$EXTERNALSYM OBJID_CURSOR}
|
|
OBJID_ALERT = DWORD($FFFFFFF6);
|
|
{$EXTERNALSYM OBJID_ALERT}
|
|
OBJID_SOUND = DWORD($FFFFFFF5);
|
|
{$EXTERNALSYM OBJID_SOUND}
|
|
|
|
//
|
|
// System Alerts (indexChild of system ALERT notification)
|
|
//
|
|
|
|
ALERT_SYSTEM_INFORMATIONAL = 1; // MB_INFORMATION
|
|
{$EXTERNALSYM ALERT_SYSTEM_INFORMATIONAL}
|
|
ALERT_SYSTEM_WARNING = 2; // MB_WARNING
|
|
{$EXTERNALSYM ALERT_SYSTEM_WARNING}
|
|
ALERT_SYSTEM_ERROR = 3; // MB_ERROR
|
|
{$EXTERNALSYM ALERT_SYSTEM_ERROR}
|
|
ALERT_SYSTEM_QUERY = 4; // MB_QUESTION
|
|
{$EXTERNALSYM ALERT_SYSTEM_QUERY}
|
|
ALERT_SYSTEM_CRITICAL = 5; // HardSysErrBox
|
|
{$EXTERNALSYM ALERT_SYSTEM_CRITICAL}
|
|
CALERT_SYSTEM = 6;
|
|
{$EXTERNALSYM CALERT_SYSTEM}
|
|
|
|
type
|
|
HWINEVENTHOOK = DWORD;
|
|
{$EXTERNALSYM HWINEVENTHOOK}
|
|
|
|
WINEVENTPROC = procedure(
|
|
hEvent: HWINEVENTHOOK;
|
|
event: DWORD;
|
|
hwnd: HWND;
|
|
idObject: LONG;
|
|
idChild: LONG;
|
|
idEventThread: DWORD;
|
|
dwmsEventTime: DWORD); stdcall;
|
|
{$EXTERNALSYM WINEVENTPROC}
|
|
TWinEventProc = WINEVENTPROC;
|
|
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
const
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
WINEVENT_OUTOFCONTEXT = $0000; // Events are ASYNC
|
|
{$EXTERNALSYM WINEVENT_OUTOFCONTEXT}
|
|
WINEVENT_SKIPOWNTHREAD = $0001; // Don't call back for events on installer's thread
|
|
{$EXTERNALSYM WINEVENT_SKIPOWNTHREAD}
|
|
WINEVENT_SKIPOWNPROCESS = $0002; // Don't call back for events on installer's process
|
|
{$EXTERNALSYM WINEVENT_SKIPOWNPROCESS}
|
|
WINEVENT_INCONTEXT = $0004; // Events are SYNC, this causes your dll to be injected into every process
|
|
{$EXTERNALSYM WINEVENT_INCONTEXT}
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
WINEVENT_32BITCALLER = $8000; // ;Internal
|
|
{$EXTERNALSYM WINEVENT_32BITCALLER}
|
|
WINEVENT_VALID = $8007; // ;Internal
|
|
{$EXTERNALSYM WINEVENT_VALID}
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
|
|
function SetWinEventHook(eventMin, eventMax: DWORD; hmodWinEventProc: HMODULE;
|
|
lpfnWinEventProc: WINEVENTPROC; idProcess, idThread, dwFlags: DWORD): HWINEVENTHOOK; stdcall;
|
|
{$EXTERNALSYM SetWinEventHook}
|
|
|
|
//
|
|
// Returns zero on failure, or a DWORD ID if success. We will clean up any
|
|
// event hooks installed by the current process when it goes away, if it
|
|
// hasn't cleaned the hooks up itself. But to dynamically unhook, call
|
|
// UnhookWinEvents().
|
|
//
|
|
|
|
function UnhookWinEvent(hEvent: HWINEVENTHOOK): BOOL; stdcall;
|
|
{$EXTERNALSYM UnhookWinEvent}
|
|
|
|
//
|
|
// If idProcess isn't zero but idThread is, will hook all threads in that
|
|
// process.
|
|
// If idThread isn't zero but idProcess is, will hook idThread only.
|
|
// If both are zero, will hook everything
|
|
//
|
|
|
|
//
|
|
// EVENT DEFINITION
|
|
//
|
|
|
|
const
|
|
EVENT_MIN = $00000001;
|
|
{$EXTERNALSYM EVENT_MIN}
|
|
EVENT_MAX = $7FFFFFFF;
|
|
{$EXTERNALSYM EVENT_MAX}
|
|
|
|
//
|
|
// EVENT_SYSTEM_SOUND
|
|
// Sent when a sound is played. Currently nothing is generating this, we
|
|
// are going to be cleaning up the SOUNDSENTRY feature in the control panel
|
|
// and will use this at that time. Applications implementing WinEvents
|
|
// are perfectly welcome to use it. Clients of IAccessible* will simply
|
|
// turn around and get back a non-visual object that describes the sound.
|
|
//
|
|
|
|
EVENT_SYSTEM_SOUND = $0001;
|
|
{$EXTERNALSYM EVENT_SYSTEM_SOUND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_ALERT
|
|
// Sent when an alert needs to be given to the user. MessageBoxes generate
|
|
// alerts for example.
|
|
//
|
|
|
|
EVENT_SYSTEM_ALERT = $0002;
|
|
{$EXTERNALSYM EVENT_SYSTEM_ALERT}
|
|
|
|
//
|
|
// EVENT_SYSTEM_FOREGROUND
|
|
// Sent when the foreground (active) window changes, even if it is changing
|
|
// to another window in the same thread as the previous one.
|
|
//
|
|
|
|
EVENT_SYSTEM_FOREGROUND = $0003;
|
|
{$EXTERNALSYM EVENT_SYSTEM_FOREGROUND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_MENUSTART
|
|
// EVENT_SYSTEM_MENUEND
|
|
// Sent when entering into and leaving from menu mode (system, app bar, and
|
|
// track popups).
|
|
//
|
|
|
|
EVENT_SYSTEM_MENUSTART = $0004;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MENUSTART}
|
|
EVENT_SYSTEM_MENUEND = $0005;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MENUEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_MENUPOPUPSTART
|
|
// EVENT_SYSTEM_MENUPOPUPEND
|
|
// Sent when a menu popup comes up and just before it is taken down. Note
|
|
// that for a call to TrackPopupMenu(), a client will see EVENT_SYSTEM_MENUSTART
|
|
// followed almost immediately by EVENT_SYSTEM_MENUPOPUPSTART for the popup
|
|
// being shown.
|
|
//
|
|
|
|
EVENT_SYSTEM_MENUPOPUPSTART = $0006;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MENUPOPUPSTART}
|
|
EVENT_SYSTEM_MENUPOPUPEND = $0007;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MENUPOPUPEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_CAPTURESTART
|
|
// EVENT_SYSTEM_CAPTUREEND
|
|
// Sent when a window takes the capture and releases the capture.
|
|
//
|
|
|
|
EVENT_SYSTEM_CAPTURESTART = $0008;
|
|
{$EXTERNALSYM EVENT_SYSTEM_CAPTURESTART}
|
|
EVENT_SYSTEM_CAPTUREEND = $0009;
|
|
{$EXTERNALSYM EVENT_SYSTEM_CAPTUREEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_MOVESIZESTART
|
|
// EVENT_SYSTEM_MOVESIZEEND
|
|
// Sent when a window enters and leaves move-size dragging mode.
|
|
//
|
|
|
|
EVENT_SYSTEM_MOVESIZESTART = $000A;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MOVESIZESTART}
|
|
EVENT_SYSTEM_MOVESIZEEND = $000B;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MOVESIZEEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_CONTEXTHELPSTART
|
|
// EVENT_SYSTEM_CONTEXTHELPEND
|
|
// Sent when a window enters and leaves context sensitive help mode.
|
|
//
|
|
|
|
EVENT_SYSTEM_CONTEXTHELPSTART = $000C;
|
|
{$EXTERNALSYM EVENT_SYSTEM_CONTEXTHELPSTART}
|
|
EVENT_SYSTEM_CONTEXTHELPEND = $000D;
|
|
{$EXTERNALSYM EVENT_SYSTEM_CONTEXTHELPEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_DRAGDROPSTART
|
|
// EVENT_SYSTEM_DRAGDROPEND
|
|
// Sent when a window enters and leaves drag drop mode. Note that it is up
|
|
// to apps and OLE to generate this, since the system doesn't know. Like
|
|
// EVENT_SYSTEM_SOUND, it will be a while before this is prevalent.
|
|
//
|
|
|
|
EVENT_SYSTEM_DRAGDROPSTART = $000E;
|
|
{$EXTERNALSYM EVENT_SYSTEM_DRAGDROPSTART}
|
|
EVENT_SYSTEM_DRAGDROPEND = $000F;
|
|
{$EXTERNALSYM EVENT_SYSTEM_DRAGDROPEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_DIALOGSTART
|
|
// EVENT_SYSTEM_DIALOGEND
|
|
// Sent when a dialog comes up and just before it goes away.
|
|
//
|
|
|
|
EVENT_SYSTEM_DIALOGSTART = $0010;
|
|
{$EXTERNALSYM EVENT_SYSTEM_DIALOGSTART}
|
|
EVENT_SYSTEM_DIALOGEND = $0011;
|
|
{$EXTERNALSYM EVENT_SYSTEM_DIALOGEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_SCROLLINGSTART
|
|
// EVENT_SYSTEM_SCROLLINGEND
|
|
// Sent when beginning and ending the tracking of a scrollbar in a window,
|
|
// and also for scrollbar controls.
|
|
//
|
|
|
|
EVENT_SYSTEM_SCROLLINGSTART = $0012;
|
|
{$EXTERNALSYM EVENT_SYSTEM_SCROLLINGSTART}
|
|
EVENT_SYSTEM_SCROLLINGEND = $0013;
|
|
{$EXTERNALSYM EVENT_SYSTEM_SCROLLINGEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_SWITCHSTART
|
|
// EVENT_SYSTEM_SWITCHEND
|
|
// Sent when beginning and ending alt-tab mode with the switch window.
|
|
//
|
|
|
|
EVENT_SYSTEM_SWITCHSTART = $0014;
|
|
{$EXTERNALSYM EVENT_SYSTEM_SWITCHSTART}
|
|
EVENT_SYSTEM_SWITCHEND = $0015;
|
|
{$EXTERNALSYM EVENT_SYSTEM_SWITCHEND}
|
|
|
|
//
|
|
// EVENT_SYSTEM_MINIMIZESTART
|
|
// EVENT_SYSTEM_MINIMIZEEND
|
|
// Sent when a window minimizes and just before it restores.
|
|
//
|
|
|
|
EVENT_SYSTEM_MINIMIZESTART = $0016;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MINIMIZESTART}
|
|
EVENT_SYSTEM_MINIMIZEEND = $0017;
|
|
{$EXTERNALSYM EVENT_SYSTEM_MINIMIZEEND}
|
|
|
|
//
|
|
// Object events
|
|
//
|
|
// The system AND apps generate these. The system generates these for
|
|
// real windows. Apps generate these for objects within their window which
|
|
// act like a separate control, e.g. an item in a list view.
|
|
//
|
|
// For all events, if you want detailed accessibility information, callers
|
|
// should
|
|
// * Call AccessibleObjectFromWindow() with the hwnd, idObject parameters
|
|
// of the event, and IID_IAccessible as the REFIID, to get back an
|
|
// IAccessible* to talk to
|
|
// * Initialize and fill in a VARIANT as VT_I4 with lVal the idChild
|
|
// parameter of the event.
|
|
// * If idChild isn't zero, call get_accChild() in the container to see
|
|
// if the child is an object in its own right. If so, you will get
|
|
// back an IDispatch* object for the child. You should release the
|
|
// parent, and call QueryInterface() on the child object to get its
|
|
// IAccessible*. Then you talk directly to the child. Otherwise,
|
|
// if get_accChild() returns you nothing, you should continue to
|
|
// use the child VARIANT. You will ask the container for the properties
|
|
// of the child identified by the VARIANT. In other words, the
|
|
// child in this case is accessible but not a full-blown object.
|
|
// Like a button on a titlebar which is 'small' and has no children.
|
|
//
|
|
|
|
//
|
|
|
|
EVENT_OBJECT_CREATE = $8000; // hwnd + ID + idChild is created item
|
|
{$EXTERNALSYM EVENT_OBJECT_CREATE}
|
|
EVENT_OBJECT_DESTROY = $8001; // hwnd + ID + idChild is destroyed item
|
|
{$EXTERNALSYM EVENT_OBJECT_DESTROY}
|
|
EVENT_OBJECT_SHOW = $8002; // hwnd + ID + idChild is shown item
|
|
{$EXTERNALSYM EVENT_OBJECT_SHOW}
|
|
EVENT_OBJECT_HIDE = $8003; // hwnd + ID + idChild is hidden item
|
|
{$EXTERNALSYM EVENT_OBJECT_HIDE}
|
|
EVENT_OBJECT_REORDER = $8004; // hwnd + ID + idChild is parent of zordering children
|
|
{$EXTERNALSYM EVENT_OBJECT_REORDER}
|
|
|
|
//
|
|
// NOTE:
|
|
// Minimize the number of notifications!
|
|
//
|
|
// When you are hiding a parent object, obviously all child objects are no
|
|
// longer visible on screen. They still have the same "visible" status,
|
|
// but are not truly visible. Hence do not send HIDE notifications for the
|
|
// children also. One implies all. The same goes for SHOW.
|
|
//
|
|
|
|
EVENT_OBJECT_FOCUS = $8005; // hwnd + ID + idChild is focused item
|
|
{$EXTERNALSYM EVENT_OBJECT_FOCUS}
|
|
EVENT_OBJECT_SELECTION = $8006; // hwnd + ID + idChild is selected item (if only one), or idChild is OBJID_WINDOW if complex
|
|
{$EXTERNALSYM EVENT_OBJECT_SELECTION}
|
|
EVENT_OBJECT_SELECTIONADD = $8007; // hwnd + ID + idChild is item added
|
|
{$EXTERNALSYM EVENT_OBJECT_SELECTIONADD}
|
|
EVENT_OBJECT_SELECTIONREMOVE = $8008; // hwnd + ID + idChild is item removed
|
|
{$EXTERNALSYM EVENT_OBJECT_SELECTIONREMOVE}
|
|
EVENT_OBJECT_SELECTIONWITHIN = $8009; // hwnd + ID + idChild is parent of changed selected items
|
|
{$EXTERNALSYM EVENT_OBJECT_SELECTIONWITHIN}
|
|
|
|
//
|
|
// NOTES:
|
|
// There is only one "focused" child item in a parent. This is the place
|
|
// keystrokes are going at a given moment. Hence only send a notification
|
|
// about where the NEW focus is going. A NEW item getting the focus already
|
|
// implies that the OLD item is losing it.
|
|
//
|
|
// SELECTION however can be multiple. Hence the different SELECTION
|
|
// notifications. Here's when to use each:
|
|
//
|
|
// (1) Send a SELECTION notification in the simple single selection
|
|
// case (like the focus) when the item with the selection is
|
|
// merely moving to a different item within a container. hwnd + ID
|
|
// is the container control, idChildItem is the new child with the
|
|
// selection.
|
|
//
|
|
// (2) Send a SELECTIONADD notification when a new item has simply been added
|
|
// to the selection within a container. This is appropriate when the
|
|
// number of newly selected items is very small. hwnd + ID is the
|
|
// container control, idChildItem is the new child added to the selection.
|
|
//
|
|
// (3) Send a SELECTIONREMOVE notification when a new item has simply been
|
|
// removed from the selection within a container. This is appropriate
|
|
// when the number of newly selected items is very small, just like
|
|
// SELECTIONADD. hwnd + ID is the container control, idChildItem is the
|
|
// new child removed from the selection.
|
|
//
|
|
// (4) Send a SELECTIONWITHIN notification when the selected items within a
|
|
// control have changed substantially. Rather than propagate a large
|
|
// number of changes to reflect removal for some items, addition of
|
|
// others, just tell somebody who cares that a lot happened. It will
|
|
// be faster an easier for somebody watching to just turn around and
|
|
// query the container control what the new bunch of selected items
|
|
// are.
|
|
//
|
|
|
|
EVENT_OBJECT_STATECHANGE = $800A; // hwnd + ID + idChild is item w/ state change
|
|
{$EXTERNALSYM EVENT_OBJECT_STATECHANGE}
|
|
EVENT_OBJECT_LOCATIONCHANGE = $800B; // hwnd + ID + idChild is moved/sized item
|
|
{$EXTERNALSYM EVENT_OBJECT_LOCATIONCHANGE}
|
|
|
|
EVENT_OBJECT_NAMECHANGE = $800C; // hwnd + ID + idChild is item w/ name change
|
|
{$EXTERNALSYM EVENT_OBJECT_NAMECHANGE}
|
|
EVENT_OBJECT_DESCRIPTIONCHANGE = $800D; // hwnd + ID + idChild is item w/ desc change
|
|
{$EXTERNALSYM EVENT_OBJECT_DESCRIPTIONCHANGE}
|
|
EVENT_OBJECT_VALUECHANGE = $800E; // hwnd + ID + idChild is item w/ value change
|
|
{$EXTERNALSYM EVENT_OBJECT_VALUECHANGE}
|
|
EVENT_OBJECT_PARENTCHANGE = $800F; // hwnd + ID + idChild is item w/ new parent
|
|
{$EXTERNALSYM EVENT_OBJECT_PARENTCHANGE}
|
|
EVENT_OBJECT_HELPCHANGE = $8010; // hwnd + ID + idChild is item w/ help change
|
|
{$EXTERNALSYM EVENT_OBJECT_HELPCHANGE}
|
|
EVENT_OBJECT_DEFACTIONCHANGE = $8011; // hwnd + ID + idChild is item w/ def action change
|
|
{$EXTERNALSYM EVENT_OBJECT_DEFACTIONCHANGE}
|
|
EVENT_OBJECT_ACCELERATORCHANGE = $8012; // hwnd + ID + idChild is item w/ keybd accel change
|
|
{$EXTERNALSYM EVENT_OBJECT_ACCELERATORCHANGE}
|
|
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
{$ENDIF JWA_IMPLEMENTATIONSECTION}
|
|
|
|
{$IFNDEF JWA_OMIT_SECTIONS}
|
|
implementation
|
|
//uses ...
|
|
{$ENDIF JWA_OMIT_SECTIONS}
|
|
|
|
{$IFNDEF JWA_INTERFACESECTION}
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
const
|
|
user32 = 'user32.dll';
|
|
{$IFDEF UNICODE}
|
|
AWSuffix = 'W';
|
|
{$ELSE}
|
|
AWSuffix = 'A';
|
|
{$ENDIF UNICODE}
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
{$IFDEF DYNAMIC_LINK}
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
|
|
var
|
|
_GetGUIThreadInfo: Pointer;
|
|
|
|
function GetGUIThreadInfo;
|
|
begin
|
|
GetProcedureAddress(_GetGUIThreadInfo, user32, 'GetGUIThreadInfo');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_GetGUIThreadInfo]
|
|
end;
|
|
end;
|
|
|
|
var
|
|
_GetWindowModuleFileNameW: Pointer;
|
|
|
|
function GetWindowModuleFileNameW;
|
|
begin
|
|
GetProcedureAddress(_GetWindowModuleFileNameW, user32, 'GetWindowModuleFileNameW');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_GetWindowModuleFileNameW]
|
|
end;
|
|
end;
|
|
|
|
var
|
|
_GetWindowModuleFileNameA: Pointer;
|
|
|
|
function GetWindowModuleFileNameA;
|
|
begin
|
|
GetProcedureAddress(_GetWindowModuleFileNameA, user32, 'GetWindowModuleFileNameA');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_GetWindowModuleFileNameA]
|
|
end;
|
|
end;
|
|
|
|
var
|
|
_GetWindowModuleFileName: Pointer;
|
|
|
|
function GetWindowModuleFileName;
|
|
begin
|
|
GetProcedureAddress(_GetWindowModuleFileName, user32, 'GetWindowModuleFileName' + AWSuffix);
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_GetWindowModuleFileName]
|
|
end;
|
|
end;
|
|
|
|
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
var
|
|
_BlockInput: Pointer;
|
|
|
|
function BlockInput;
|
|
begin
|
|
GetProcedureAddress(_BlockInput, user32, 'BlockInput');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_BlockInput]
|
|
end;
|
|
end;
|
|
|
|
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
var
|
|
_SendInput: Pointer;
|
|
|
|
function SendInput;
|
|
begin
|
|
GetProcedureAddress(_SendInput, user32, 'SendInput');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_SendInput]
|
|
end;
|
|
end;
|
|
|
|
|
|
var
|
|
_NotifyWinEvent: Pointer;
|
|
|
|
procedure NotifyWinEvent;
|
|
begin
|
|
GetProcedureAddress(_NotifyWinEvent, user32, 'NotifyWinEvent');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_NotifyWinEvent]
|
|
end;
|
|
end;
|
|
|
|
|
|
var
|
|
_SetWinEventHook: Pointer;
|
|
|
|
function SetWinEventHook;
|
|
begin
|
|
GetProcedureAddress(_SetWinEventHook, user32, 'SetWinEventHook');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_SetWinEventHook]
|
|
end;
|
|
end;
|
|
|
|
var
|
|
_UnhookWinEvent: Pointer;
|
|
|
|
function UnhookWinEvent;
|
|
begin
|
|
GetProcedureAddress(_UnhookWinEvent, user32, 'UnhookWinEvent');
|
|
asm
|
|
MOV ESP, EBP
|
|
POP EBP
|
|
JMP [_UnhookWinEvent]
|
|
end;
|
|
end;
|
|
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
{$ELSE}
|
|
|
|
function BlockInput; external user32 name 'BlockInput';
|
|
{$IFNDEF JWA_INCLUDEMODE}
|
|
function GetGUIThreadInfo; external user32 name 'GetGUIThreadInfo';
|
|
function GetWindowModuleFileNameW; external user32 name 'GetWindowModuleFileNameW';
|
|
function GetWindowModuleFileNameA; external user32 name 'GetWindowModuleFileNameA';
|
|
function GetWindowModuleFileName; external user32 name 'GetWindowModuleFileName' + AWSuffix;
|
|
function SendInput; external user32 name 'SendInput';
|
|
procedure NotifyWinEvent; external user32 name 'NotifyWinEvent';
|
|
function SetWinEventHook; external user32 name 'SetWinEventHook';
|
|
function UnhookWinEvent; external user32 name 'UnhookWinEvent';
|
|
{$ENDIF JWA_INCLUDEMODE}
|
|
|
|
{$ENDIF DYNAMIC_LINK}
|
|
{$ENDIF JWA_INTERFACESECTION}
|
|
|
|
{$IFNDEF JWA_OMIT_SECTIONS}
|
|
end.
|
|
{$ENDIF JWA_OMIT_SECTIONS}
|