Path: blob/master/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspector.cpp
40957 views
/*1* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* A sample Assistive Technology which queries the JavaVM to get the Java27* Accessibility information available for a Java UI object, using the Java28* Access Bridge.29*/3031#include <windows.h> // includes basic windows functionality32#include <jni.h>3334#include "jaccessinspectorResource.h"35#include "AccessBridgeCalls.h"36#include "AccessBridgeCallbacks.h"3738#include <stdio.h>39#include <time.h>40#include <string.h>4142#include "jaccessinspector.h"43#include "AccessInfo.h"44#include "MessageHistory.h"4546#define TIMER_ID 147#define DISPLAY_INFO_MESSAGE WM_USER+148#define DISPLAY_HWND_INFO_MESSAGE WM_USER+24950HWND theDialogWindow;51HWND theGoToDialogWindow;52HINSTANCE theInstance;53BOOL theAccessBridgeLoadedFlag;5455HHOOK prevKbdHook;56HHOOK prevMouseHook;5758BOOL updateMouse;59BOOL updateF1;60BOOL updateF2;6162BOOL trackMouse;63BOOL trackMouseExited;64BOOL trackMouseClicked;65BOOL trackMousePressed;66BOOL trackMouseReleased;6768BOOL trackFocus;69BOOL trackFocusLost;70BOOL trackCaret;71BOOL trackShutdown;7273BOOL trackMenuSelected;74BOOL trackMenuDeselected;75BOOL trackMenuCanceled;7677BOOL trackPopupVisible;78BOOL trackPopupInvisible;79BOOL trackPopupCanceled;8081//BOOL trackPropertyChange;8283BOOL trackPropertyNameChange;84BOOL trackPropertyDescriptionChange;85BOOL trackPropertyStateChange;86BOOL trackPropertyValueChange;87BOOL trackPropertySelectionChange;88BOOL trackPropertyTextChange;89BOOL trackPropertyCaretChange;90BOOL trackPropertyVisibleDataChange;91BOOL trackPropertyChildChange;92BOOL trackPropertyActiveDescendentChange;93BOOL trackPropertyTableModelChange;949596FILE *logfile = NULL;9798MessageHistory g_MessageHistory;99100/**101* WinMain102*103*/104int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd) {105MSG msg;106107g_LogStringCallback = AddToMessageHistory;108theInstance = hInst;109theDialogWindow = NULL;110theGoToDialogWindow = NULL;111112updateF1 = FALSE;113updateF2 = FALSE;114updateMouse = FALSE;115116theAccessBridgeLoadedFlag = FALSE;117118ReadActiveEventOptionsFromRegistry ();119120if (InitWindow(hInst)) {121if (initializeAccessBridge() == TRUE) {122theAccessBridgeLoadedFlag = TRUE;123ApplyEventOptions(theDialogWindow);124EnableMessageNavButtons();125HACCEL hAccel =126::LoadAccelerators (theInstance, MAKEINTRESOURCE(IDR_ACCELERATOR));127128while (GetMessage(&msg, NULL, 0, 0)) {129if ( FALSE == TranslateAccelerator(theDialogWindow, hAccel, &msg) ) {130if ( ( ( NULL == theDialogWindow ) ||131( FALSE == IsDialogMessage(theDialogWindow, &msg) ) ) &&132( ( NULL == theGoToDialogWindow ) ||133( FALSE == IsDialogMessage(theGoToDialogWindow, &msg) ) ) ) {134TranslateMessage(&msg);135DispatchMessage(&msg);136}137}138}139if (theAccessBridgeLoadedFlag == TRUE) {140shutdownAccessBridge();141}142SaveActiveEventOptionsToRegistry ();143}144}145return(0);146}147148char szAppName [] = "JACCESSINSPECTORWINDOW";149150/**151* Real(tm) MS-Windows window initialization152*153*/154BOOL InitWindow (HANDLE hInstance) {155theDialogWindow = CreateDialog((struct HINSTANCE__ *)hInstance,156szAppName,157NULL,158jaccessinspectorDialogProc);159160// If window could not be created, return "failure".161if (!theDialogWindow)162return FALSE;163164if (logfile == null) {165logfile = fopen(JACCESSINSPECTOR_LOG, "w"); // overwrite existing log file166logString(logfile, "Starting jaccessinspector.exe %s\n", getTimeAndDate());167}168169// Make the window visible, update its client area, & return "success".170SetWindowText(theDialogWindow, "jaccessinspector");171ShowWindow(theDialogWindow, SW_SHOWNORMAL);172UpdateWindow(theDialogWindow);173174return TRUE;175}176177/**178* Display Accessible information about the object under the mouse179*/180void displayAccessibleInfo(long vmID, AccessibleContext ac, int x, int y) {181char buffer[HUGE_BUFSIZE];182183getAccessibleInfo(vmID, ac, x, y, buffer, (int)(sizeof(buffer)));184displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)buffer);185}186187/**188* Display Java event info189*/190void displayJavaEvent(long vmID, AccessibleContext ac, char *announcement) {191char buffer[HUGE_BUFSIZE];192char *bufOffset;193194strncpy(buffer, announcement, sizeof(buffer));195196bufOffset = (char *)(buffer + strlen(buffer));197getAccessibleInfo( vmID, ac, -1, -1, bufOffset,198(int)(sizeof(buffer) - strlen(buffer)) );199displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)buffer);200}201202203/**204* Display Accessible propertyChange event info205*/206void displayAccessiblePropertyChange(long vmID, AccessibleContext ac,207char *announcement) {208char buffer[HUGE_BUFSIZE];209char *bufOffset;210211strncpy(buffer, announcement, sizeof(buffer));212213bufOffset = (char *) (buffer + strlen(buffer));214getAccessibleInfo( vmID, ac, -1, -1, bufOffset,215(int)(sizeof(buffer) - strlen(buffer)) );216displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)buffer);217}218219220/**221* Update display under mouse when it moves222*/223void echoMouseObject() {224long vmID;225AccessibleContext acParent;226AccessibleContext ac;227POINT p;228HWND hwnd;229RECT windowRect;230231GetCursorPos(&p);232hwnd = WindowFromPoint(p);233if (GetAccessibleContextFromHWND(hwnd, &vmID, &acParent)) {234GetWindowRect(hwnd, &windowRect);235// send the point in global coordinates; Java will handle it!236if (GetAccessibleContextAt(vmID, acParent, (jint) p.x, (jint) p.y, &ac)) {237displayAccessibleInfo(vmID, ac, p.x, p.y); // can handle null238ReleaseJavaObject(vmID, ac);239}240}241}242243244/**245* Update display under HWND the mouse is in246*/247void echoMouseHWNDObject() {248long vmID;249AccessibleContext ac;250POINT p;251HWND hwnd;252253GetCursorPos(&p);254hwnd = WindowFromPoint(p);255256if (GetAccessibleContextFromHWND(hwnd, &vmID, &ac)) {257displayAccessibleInfo(vmID, ac, 0, 0); // can handle null258ReleaseJavaObject(vmID, ac);259}260}261262/**263* Display Accessible information about the object that has focus in264* the topmost Java HWND265*266*/267void displayFocusedObject() {268HWND hWnd;269long vmID;270AccessibleContext ac;271272hWnd = GetTopWindow(NULL);273while (hWnd != NULL) {274if (IsJavaWindow(hWnd)) {275if (GetAccessibleContextWithFocus(hWnd, &vmID, &ac) == TRUE) {276displayAccessibleInfo(vmID, ac, 0, 0);277ReleaseJavaObject(vmID, ac);278}279return;280} else {281hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);282}283}284}285286/*287* Handle notification of the Java application shutting down288*/289void HandleJavaShutdown(long vmID) {290char s[1024];291wsprintf(s, "Java VM 0x%X terminated\r\n\r\n", vmID);292293displayJavaEvent(vmID, null, s); // intentially passing null AccessibleContext294displayAndLog(theDialogWindow, cjaccessinspectorText, logfile, (char *)s);295}296297/**298* Handle a FocusGained event299*/300void HandleJavaFocusGained(long vmID, FocusEvent event, AccessibleContext ac) {301302char s[1024];303wsprintf(s, "FocusGained\r\n\r\n");304305if (ac != (AccessibleContext) 0) {306displayJavaEvent(vmID, ac, s);307}308309ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks310ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks311}312313/**314* Handle a FocusLost event315*/316void HandleJavaFocusLost(long vmID, FocusEvent event, AccessibleContext ac) {317318// NOTE: calling GetAccessibleContextWithFocus() after a FocusLost event319// would result in a null AccessibleContext being returned, since320// at that point, no object has the focus. If the topmost window321// does not belong to a JavaVM, then no component within a JavaVM322// will have the focus (and again, GetAccessibleContextWithFocus()323// will return a null AccessibleContext). You should always get324// a FocusLost event when a window not belonging to a JavaVM becomes325// topmost.326327char s[1024];328wsprintf(s, "FocusLost\r\n\r\n");329330if (ac != (AccessibleContext) 0) {331displayJavaEvent(vmID, ac, s);332}333/*334if (ac != (AccessibleContext) 0) {335displayAccessibleInfo(vmID, ac, 0, 0);336}337*/338ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks339ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks340}341342/**343* Handle a CaretUpdate event344*/345void HandleJavaCaretUpdate(long vmID, CaretEvent event, AccessibleContext ac) {346if (ac != (AccessibleContext) 0) {347displayAccessibleInfo(vmID, ac, 0, 0);348}349ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks350ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks351}352353/**354* Handle a MouseClicked event355*/356void HandleMouseClicked(long vmID, MouseEvent event, AccessibleContext ac) {357if (ac != (AccessibleContext) 0) {358displayAccessibleInfo(vmID, ac, 0, 0);359}360ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks361ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks362}363364/**365* Handle a MouseEntered event366*/367void HandleMouseEntered(long vmID, MouseEvent event, AccessibleContext ac) {368if (ac != (AccessibleContext) 0) {369displayAccessibleInfo(vmID, ac, 0, 0);370}371372ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks373ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks374}375376/**377* Handle a MouseExited event378*/379void HandleMouseExited(long vmID, MouseEvent event, AccessibleContext ac) {380if (ac != (AccessibleContext) 0) {381displayAccessibleInfo(vmID, ac, 0, 0);382}383ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks384ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks385}386387/**388* Handle a MousePressed event389*/390void HandleMousePressed(long vmID, MouseEvent event, AccessibleContext ac) {391if (ac != (AccessibleContext) 0) {392displayAccessibleInfo(vmID, ac, 0, 0);393}394ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks395ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks396}397398/**399* Handle a MouseReleased event400*/401void HandleMouseReleased(long vmID, MouseEvent event, AccessibleContext ac) {402if (ac != (AccessibleContext) 0) {403displayAccessibleInfo(vmID, ac, 0, 0);404}405ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks406ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks407}408409/**410* Handle a MenuCanceled event411*/412void HandleMenuCanceled(long vmID, MenuEvent event, AccessibleContext ac) {413if (ac != (AccessibleContext) 0) {414displayAccessibleInfo(vmID, ac, 0, 0);415}416ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks417ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks418}419420/**421* Handle a MenuDeselected event422*/423void HandleMenuDeselected(long vmID, MenuEvent event, AccessibleContext ac) {424if (ac != (AccessibleContext) 0) {425displayAccessibleInfo(vmID, ac, 0, 0);426}427ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks428ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks429}430431/**432* Handle a MenuSelected event433*/434void HandleMenuSelected(long vmID, MenuEvent event, AccessibleContext ac) {435if (ac != (AccessibleContext) 0) {436displayAccessibleInfo(vmID, ac, 0, 0);437}438ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks439ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks440}441442/**443* Handle a PopupMenuCanceled event444*/445void HandlePopupMenuCanceled(long vmID, MenuEvent event, AccessibleContext ac) {446if (ac != (AccessibleContext) 0) {447displayAccessibleInfo(vmID, ac, 0, 0);448}449ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks450ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks451}452453/**454* Handle a PopupMenuWillBecomeInvisible event455*/456void HandlePopupMenuWillBecomeInvisible(long vmID, MenuEvent event, AccessibleContext ac) {457if (ac != (AccessibleContext) 0) {458displayAccessibleInfo(vmID, ac, 0, 0);459}460ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks461ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks462}463464/**465* Handle a PopupMenuWillBecomeVisible event466*/467void HandlePopupMenuWillBecomeVisible(long vmID, MenuEvent event, AccessibleContext ac) {468if (ac != (AccessibleContext) 0) {469displayAccessibleInfo(vmID, ac, 0, 0);470}471ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks472ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks473}474475476477478/**479* Handle a HandlePropertyNameChange event480*/481void HandlePropertyNameChange(long vmID, PropertyChangeEvent event, AccessibleContext ac,482wchar_t *oldName, wchar_t *newName) {483char s[1024];484wsprintf(s, "Name changed event: old = %ls; new = %ls\r\n\r\n", oldName, newName);485486if (ac != (AccessibleContext) 0) {487displayAccessiblePropertyChange(vmID, ac, s);488}489ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks490ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks491}492493/**494* Handle a HandlePropertyDescriptionChange event495*/496void HandlePropertyDescriptionChange( long vmID,497PropertyChangeEvent event,498AccessibleContext ac,499wchar_t *oldDescription,500wchar_t *newDescription ) {501char s[1024];502wsprintf( s, "Description changed event: old = %ls; new = %ls\r\n\r\n",503oldDescription, newDescription );504505if (ac != (AccessibleContext) 0) {506displayAccessiblePropertyChange(vmID, ac, s);507}508ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks509ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks510}511512/**513* Handle a HandlePropertyStateChange event514*/515void HandlePropertyStateChange( long vmID, PropertyChangeEvent event,516AccessibleContext ac,517wchar_t *oldState, wchar_t *newState ) {518char s[1024];519wsprintf( s, "State changed event: old = %ls; new = %ls\r\n\r\n",520oldState, newState );521522if (ac != (AccessibleContext) 0) {523displayAccessiblePropertyChange(vmID, ac, s);524}525ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks526ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks527}528529/**530* Handle a HandlePropertyValueChange event531*/532void HandlePropertyValueChange( long vmID, PropertyChangeEvent event,533AccessibleContext ac,534wchar_t *oldValue, wchar_t *newValue ) {535char s[1024];536wsprintf( s, "Value changed event: old = %ls; new = %ls\r\n\r\n",537oldValue, newValue );538539if (ac != (AccessibleContext) 0) {540displayAccessiblePropertyChange(vmID, ac, s);541}542ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks543ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks544}545546/**547* Handle a HandlePropertySelectionChange event548*/549void HandlePropertySelectionChange( long vmID, PropertyChangeEvent event,550AccessibleContext ac ) {551if (ac != (AccessibleContext) 0) {552displayAccessiblePropertyChange( vmID, ac,553"Selection changed event\r\n\r\n" );554}555ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks556ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks557}558559/**560* Handle a HandlePropertyTextChange event561*/562void HandlePropertyTextChange( long vmID, PropertyChangeEvent event,563AccessibleContext ac ) {564if (ac != (AccessibleContext) 0) {565displayAccessiblePropertyChange(vmID, ac, "Text changed event\r\n\r\n");566}567ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks568ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks569}570571/**572* Handle a HandlePropertyCaretChange event573*/574void HandlePropertyCaretChange( long vmID, PropertyChangeEvent event,575AccessibleContext ac,576int oldPosition, int newPosition ) {577char s[1024];578579wsprintf( s, "Caret changed event: oldPosition = %d; newPosition = %d\r\n\r\n",580oldPosition, newPosition );581582if (ac != (AccessibleContext) 0) {583displayAccessiblePropertyChange(vmID, ac, s);584}585ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks586ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks587}588589/**590* Handle a HandlePropertyVisibleDataChange event591*/592void HandlePropertyVisibleDataChange( long vmID, PropertyChangeEvent event,593AccessibleContext ac ) {594if (ac != (AccessibleContext) 0) {595displayAccessiblePropertyChange( vmID, ac,596"VisibleData changed event\r\n\r\n" );597}598ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks599ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks600}601602/**603* Handle a HandlePropertyChildChange event604*/605void HandlePropertyChildChange( long vmID, PropertyChangeEvent event,606AccessibleContext ac,607JOBJECT64 oldChild, JOBJECT64 newChild ) {608char buffer[HUGE_BUFSIZE];609char *bufOffset;610611sprintf( buffer,612"Child property changed event:\r\n=======================\r\n\r\n" );613614if (oldChild != 0) {615strncat(buffer, "Old Accessible Child info:\r\n\r\n", sizeof(buffer));616bufOffset = (char *) (buffer + strlen(buffer));617getAccessibleInfo( vmID, oldChild, 0, 0, bufOffset,618(int)(sizeof(buffer) - strlen(buffer)) );619strncat(buffer, "\r\n\r\n", sizeof(buffer));620}621622if (newChild != 0) {623strncat(buffer, "New Accessible Child info:\r\n\r\n", sizeof(buffer));624bufOffset = (char *) (buffer + strlen(buffer));625getAccessibleInfo( vmID, newChild, 0, 0, bufOffset,626(int)(sizeof(buffer) - strlen(buffer)) );627strncat(buffer, "\r\n\r\n", sizeof(buffer));628}629630if (ac != (AccessibleContext) 0) {631displayAccessiblePropertyChange(vmID, ac, buffer);632}633634ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks635ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks636ReleaseJavaObject(vmID, oldChild); // must always release, to stave off memory leaks637ReleaseJavaObject(vmID, newChild); // must always release, to stave off memory leaks638}639640/**641* Handle a HandlePropertyActiveDescendentChange event642*/643void HandlePropertyActiveDescendentChange( long vmID, PropertyChangeEvent event,644AccessibleContext ac,645JOBJECT64 oldActiveDescendent,646JOBJECT64 newActiveDescendent ) {647char buffer[HUGE_BUFSIZE];648649sprintf( buffer,650"ActiveDescendent property changed event:\r\n=======================\r\n\r\n" );651652#ifdef _notdef653char *bufOffset;654if (oldActiveDescendent != 0) {655strncat(buffer, "Old Accessible ActiveDescendent info:\r\n\r\n", sizeof(buffer));656bufOffset = (char *) (buffer + strlen(buffer));657getAccessibleInfo( vmID, oldActiveDescendent, 0, 0, bufOffset,658(int)(sizeof(buffer) - strlen(buffer)) );659strncat(buffer, "\r\n\r\n", sizeof(buffer));660}661662if (newActiveDescendent != 0) {663strncat( buffer, "New Accessible ActiveDescendent info:\r\n\r\n",664sizeof(buffer) );665bufOffset = (char *) (buffer + strlen(buffer));666getAccessibleInfo( vmID, newActiveDescendent, 0, 0, bufOffset,667(int)(sizeof(buffer) - strlen(buffer)) );668strncat(buffer, "\r\n\r\n", sizeof(buffer));669}670#endif _notdef671672if (newActiveDescendent != (AccessibleContext) 0) {673displayAccessiblePropertyChange(vmID, newActiveDescendent, buffer);674}675676ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks677ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks678ReleaseJavaObject(vmID, oldActiveDescendent); // must always release, to stave off memory leaks679ReleaseJavaObject(vmID, newActiveDescendent); // must always release, to stave off memory leaks680}681682683/**684* Handle a HandlePropertyTableModelChange event685*/686void HandlePropertyTableModelChange( long vmID, PropertyChangeEvent event,687AccessibleContext ac,688wchar_t *oldValue, wchar_t *newValue ) {689690char s[1024];691wsprintf( s, "Table Model Change: old = %ls; new = %ls\r\n\r\n",692oldValue, newValue );693694if (ac != (AccessibleContext) 0) {695displayAccessiblePropertyChange(vmID, ac, s);696}697ReleaseJavaObject(vmID, ac); // must always release, to stave off memory leaks698ReleaseJavaObject(vmID, event); // must always release, to stave off memory leaks699}700701702703#define DOWN_UP_FLAG 1<<31704705void CALLBACK TimerProc(HWND hWnd, UINT uTimerMsg, UINT uTimerID, DWORD dwTime) {706// when mouse settles from movement707KillTimer(hWnd, uTimerID);708if (updateMouse == TRUE) {709PostMessage(theDialogWindow, DISPLAY_INFO_MESSAGE, 0, 0);710}711}712713LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {714// on mouse-up of F1715if (code < 0) {716CallNextHookEx(prevKbdHook, code, wParam, lParam);717} else if (wParam == VK_F1 && lParam & DOWN_UP_FLAG && updateF1) {718PostMessage(theDialogWindow, DISPLAY_INFO_MESSAGE, wParam, lParam);719} else if (wParam == VK_F2 && lParam & DOWN_UP_FLAG && updateF2) {720PostMessage(theDialogWindow, DISPLAY_HWND_INFO_MESSAGE, wParam, lParam);721}722return 0;723}724725LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) {726// when mouse settles from movement727if (code < 0) {728CallNextHookEx(prevMouseHook, code, wParam, lParam);729} else {730// reset the timer every time the mouse moves731KillTimer(theDialogWindow, TIMER_ID);732SetTimer(theDialogWindow, TIMER_ID, 1000, (TIMERPROC)TimerProc);733}734return 0;735}736737void exitjaccessinspector(HWND hWnd) {738EndDialog(hWnd, TRUE);739PostQuitMessage (0);740}741742#define INSTALL_EVENT_LISTENER(toggleVal, setFP, handler) \743if (toggleVal) { \744setFP(handler); \745}746747void reinstallEventListeners() {748INSTALL_EVENT_LISTENER(trackMouse, SetMouseEntered, HandleMouseEntered);749INSTALL_EVENT_LISTENER(trackMouseExited, SetMouseExited, HandleMouseExited);750INSTALL_EVENT_LISTENER(trackMouseClicked, SetMouseClicked, HandleMouseClicked);751INSTALL_EVENT_LISTENER(trackMousePressed, SetMousePressed, HandleMousePressed);752INSTALL_EVENT_LISTENER(trackMouseReleased, SetMouseReleased, HandleMouseReleased);753INSTALL_EVENT_LISTENER(trackShutdown, SetJavaShutdown, HandleJavaShutdown);754INSTALL_EVENT_LISTENER(trackFocus, SetFocusGained, HandleJavaFocusGained);755INSTALL_EVENT_LISTENER(trackFocusLost, SetFocusLost, HandleJavaFocusLost);756INSTALL_EVENT_LISTENER(trackCaret, SetCaretUpdate, HandleJavaCaretUpdate);757758INSTALL_EVENT_LISTENER(trackMenuSelected, SetMenuSelected, HandleMenuSelected);759INSTALL_EVENT_LISTENER(trackMenuDeselected, SetMenuDeselected, HandleMenuDeselected);760INSTALL_EVENT_LISTENER(trackMenuCanceled, SetMenuCanceled, HandleMenuCanceled);761762INSTALL_EVENT_LISTENER( trackPopupVisible, SetPopupMenuWillBecomeVisible,763HandlePopupMenuWillBecomeVisible );764INSTALL_EVENT_LISTENER( trackPopupInvisible, SetPopupMenuWillBecomeInvisible,765HandlePopupMenuWillBecomeInvisible );766INSTALL_EVENT_LISTENER( trackPopupCanceled, SetPopupMenuCanceled,767HandlePopupMenuCanceled );768769INSTALL_EVENT_LISTENER( trackPropertyNameChange, SetPropertyNameChange,770HandlePropertyNameChange);771INSTALL_EVENT_LISTENER( trackPropertyDescriptionChange,772SetPropertyDescriptionChange,773HandlePropertyDescriptionChange );774INSTALL_EVENT_LISTENER( trackPropertyStateChange, SetPropertyStateChange,775HandlePropertyStateChange );776INSTALL_EVENT_LISTENER( trackPropertyValueChange, SetPropertyValueChange,777HandlePropertyValueChange );778INSTALL_EVENT_LISTENER( trackPropertySelectionChange,779SetPropertySelectionChange,780HandlePropertySelectionChange );781INSTALL_EVENT_LISTENER( trackPropertyTextChange, SetPropertyTextChange,782HandlePropertyTextChange );783INSTALL_EVENT_LISTENER( trackPropertyCaretChange, SetPropertyCaretChange,784HandlePropertyCaretChange );785INSTALL_EVENT_LISTENER( trackPropertyVisibleDataChange,786SetPropertyVisibleDataChange,787HandlePropertyVisibleDataChange );788INSTALL_EVENT_LISTENER( trackPropertyChildChange, SetPropertyChildChange,789HandlePropertyChildChange );790INSTALL_EVENT_LISTENER( trackPropertyActiveDescendentChange,791SetPropertyActiveDescendentChange,792HandlePropertyActiveDescendentChange );793INSTALL_EVENT_LISTENER( trackPropertyTableModelChange,794SetPropertyTableModelChange,795HandlePropertyTableModelChange );796}797798799#define TRACK_EVENT_TOGGLE(menuItem, toggleVal, setFP, handler) \800case menuItem: \801menu = GetMenu(hWnd); \802if (toggleVal) { \803toggleVal = FALSE; \804CheckMenuItem(menu, menuItem, \805MF_BYCOMMAND | MF_UNCHECKED); \806setFP(NULL); \807} else { \808toggleVal = TRUE; \809CheckMenuItem(menu, menuItem, \810MF_BYCOMMAND | MF_CHECKED); \811setFP(handler); \812} \813MaybeCheckMonitorTheSameEventsAsJAWS(menu); \814MaybeCheckMonitorAllEvents(menu); \815return TRUE816817INT_PTR CALLBACK jaccessinspectorDialogProc( HWND hWnd, UINT message,818WPARAM wParam, LPARAM lParam ) {819const int minWindowWidth = 540;820const int minWindowHeight = 300;821static int titleBarHeight = ::GetSystemMetrics(SM_CYSIZE);822static int menuBarHeight = ::GetSystemMetrics(SM_CYMENU);823static int borderHeight = ::GetSystemMetrics(SM_CYBORDER);824static int borderWidth = ::GetSystemMetrics(SM_CXBORDER);825static int verticalScrollBarWidth = ::GetSystemMetrics(SM_CXVSCROLL);826int command;827short width, height;828HWND dlgItem;829RECT dlgItemRect;830RECT dialogBoxRect;831LONG lT;832HMENU menu;833DWORD lastError = 0;834835switch (message) {836837case WM_CREATE:838return 0;839840case WM_INITDIALOG:841CheckMenuItem(GetMenu(hWnd), cAccessBridgeDLLLoaded, MF_BYCOMMAND | MF_CHECKED);842return TRUE;843844case WM_CLOSE:845exitjaccessinspector(hWnd);846return TRUE;847848case WM_SIZE:849width = LOWORD(lParam);850height = HIWORD(lParam);851dlgItem = GetDlgItem(theDialogWindow, cjaccessinspectorText);852::GetWindowRect(dlgItem, &dlgItemRect);853::GetWindowRect(theDialogWindow, &dialogBoxRect);854lT = dlgItemRect.top - dialogBoxRect.top - titleBarHeight -855menuBarHeight + (borderHeight * 4);856SetWindowPos( dlgItem, NULL, 0, 0,857width - (borderWidth * 2) - verticalScrollBarWidth,858height - lT, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);859return FALSE; // let windows finish handling this860861case WM_GETMINMAXINFO:862{863LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;864lpMMI->ptMinTrackSize.x = minWindowWidth;865lpMMI->ptMinTrackSize.y = minWindowHeight;866return TRUE;867}868break;869870case WM_COMMAND:871command = LOWORD(wParam);872873switch(command) {874case cAccessBridgeDLLLoaded: // toggle; unload or load AccessBridge875if (theAccessBridgeLoadedFlag) {876shutdownAccessBridge();877theAccessBridgeLoadedFlag = FALSE;878CheckMenuItem( GetMenu(hWnd), cAccessBridgeDLLLoaded,879MF_BYCOMMAND | MF_UNCHECKED );880} else {881theAccessBridgeLoadedFlag = initializeAccessBridge();882if (theAccessBridgeLoadedFlag) {883CheckMenuItem( GetMenu(hWnd), cAccessBridgeDLLLoaded,884MF_BYCOMMAND | MF_CHECKED );885reinstallEventListeners();886}887}888return TRUE;889890case cExitMenuItem:891exitjaccessinspector(hWnd);892return TRUE;893894TRACK_EVENT_TOGGLE( cTrackMouseMenuItem, trackMouse, SetMouseEntered,895HandleMouseEntered );896TRACK_EVENT_TOGGLE( cTrackMouseExitedMenuItem, trackMouseExited,897SetMouseExited, HandleMouseExited );898TRACK_EVENT_TOGGLE( cTrackMouseClickedMenuItem, trackMouseClicked,899SetMouseClicked, HandleMouseClicked );900TRACK_EVENT_TOGGLE( cTrackMousePressedMenuItem, trackMousePressed,901SetMousePressed, HandleMousePressed );902TRACK_EVENT_TOGGLE( cTrackMouseReleasedMenuItem, trackMouseReleased,903SetMouseReleased, HandleMouseReleased );904TRACK_EVENT_TOGGLE( cTrackShutdownMenuItem, trackShutdown,905SetJavaShutdown, HandleJavaShutdown );906TRACK_EVENT_TOGGLE( cTrackFocusMenuItem, trackFocus, SetFocusGained,907HandleJavaFocusGained );908TRACK_EVENT_TOGGLE( cTrackFocusLostMenuItem, trackFocusLost,909SetFocusLost, HandleJavaFocusLost );910TRACK_EVENT_TOGGLE( cTrackCaretMenuItem, trackCaret, SetCaretUpdate,911HandleJavaCaretUpdate );912913TRACK_EVENT_TOGGLE( cTrackMenuSelectedMenuItem, trackMenuSelected,914SetMenuSelected, HandleMenuSelected );915TRACK_EVENT_TOGGLE( cTrackMenuDeselectedMenuItem, trackMenuDeselected,916SetMenuDeselected, HandleMenuDeselected );917TRACK_EVENT_TOGGLE( cTrackMenuCanceledItem, trackMenuCanceled,918SetMenuCanceled, HandleMenuCanceled );919920TRACK_EVENT_TOGGLE( cTrackPopupBecomeVisibleMenuItem, trackPopupVisible,921SetPopupMenuWillBecomeVisible,922HandlePopupMenuWillBecomeVisible );923TRACK_EVENT_TOGGLE( cTrackPopupBecomeInvisibleMenuItem,924trackPopupInvisible,925SetPopupMenuWillBecomeInvisible,926HandlePopupMenuWillBecomeInvisible );927TRACK_EVENT_TOGGLE( cTrackPopupCanceledItem, trackPopupCanceled,928SetPopupMenuCanceled, HandlePopupMenuCanceled );929930TRACK_EVENT_TOGGLE( cTrackPropertyNameItem, trackPropertyNameChange,931SetPropertyNameChange, HandlePropertyNameChange );932TRACK_EVENT_TOGGLE( cTrackPropertyDescriptionItem,933trackPropertyDescriptionChange,934SetPropertyDescriptionChange,935HandlePropertyDescriptionChange );936TRACK_EVENT_TOGGLE( cTrackPropertyStateItem, trackPropertyStateChange,937SetPropertyStateChange, HandlePropertyStateChange );938TRACK_EVENT_TOGGLE( cTrackPropertyValueItem, trackPropertyValueChange,939SetPropertyValueChange, HandlePropertyValueChange );940TRACK_EVENT_TOGGLE( cTrackPropertySelectionItem,941trackPropertySelectionChange,942SetPropertySelectionChange,943HandlePropertySelectionChange );944TRACK_EVENT_TOGGLE( cTrackPropertyTextItem, trackPropertyTextChange,945SetPropertyTextChange, HandlePropertyTextChange );946TRACK_EVENT_TOGGLE( cTrackPropertyCaretItem, trackPropertyCaretChange,947SetPropertyCaretChange, HandlePropertyCaretChange );948TRACK_EVENT_TOGGLE( cTrackPropertyVisibleDataItem,949trackPropertyVisibleDataChange,950SetPropertyVisibleDataChange,951HandlePropertyVisibleDataChange );952TRACK_EVENT_TOGGLE( cTrackPropertyChildItem, trackPropertyChildChange,953SetPropertyChildChange, HandlePropertyChildChange );954TRACK_EVENT_TOGGLE( cTrackPropertyActiveDescendentItem,955trackPropertyActiveDescendentChange,956SetPropertyActiveDescendentChange,957HandlePropertyActiveDescendentChange );958TRACK_EVENT_TOGGLE( cTrackPropertyTableModelChangeItem,959trackPropertyTableModelChange,960SetPropertyTableModelChange,961HandlePropertyTableModelChange );962963case cUpdateFromMouseMenuItem:964menu = GetMenu(hWnd);965if (updateMouse) {966updateMouse = FALSE;967CheckMenuItem( menu, cUpdateFromMouseMenuItem,968MF_BYCOMMAND | MF_UNCHECKED );969UnhookWindowsHookEx((HHOOK)MouseProc);970KillTimer(hWnd, TIMER_ID);971} else {972updateMouse = TRUE;973CheckMenuItem( menu, cUpdateFromMouseMenuItem,974MF_BYCOMMAND | MF_CHECKED );975prevMouseHook = SetWindowsHookEx( WH_MOUSE, MouseProc,976theInstance,977::GetCurrentThreadId() );978if (! prevMouseHook) {979lastError = ::GetLastError();980}981}982return TRUE;983984case cUpdateWithF1Item:985menu = GetMenu(hWnd);986if (updateF1) {987updateF1 = FALSE;988CheckMenuItem( menu, cUpdateWithF1Item,989MF_BYCOMMAND | MFS_UNCHECKED );990UnhookWindowsHookEx((HHOOK)KeyboardProc);991} else {992updateF1 = TRUE;993CheckMenuItem( menu, cUpdateWithF1Item,994MF_BYCOMMAND | MFS_CHECKED );995prevKbdHook = SetWindowsHookEx( WH_KEYBOARD, KeyboardProc,996theInstance,997::GetCurrentThreadId() );998if (! prevKbdHook) {999lastError = ::GetLastError();1000}1001}1002return TRUE;10031004case cUpdateWithF2Item:1005menu = GetMenu(hWnd);1006if (updateF2) {1007updateF2 = FALSE;1008CheckMenuItem( menu, cUpdateWithF2Item,1009MF_BYCOMMAND | MFS_UNCHECKED );1010UnhookWindowsHookEx((HHOOK)KeyboardProc);1011} else {1012updateF2 = TRUE;1013CheckMenuItem(menu, cUpdateWithF2Item,1014MF_BYCOMMAND | MFS_CHECKED);1015prevKbdHook = SetWindowsHookEx( WH_KEYBOARD, KeyboardProc,1016theInstance, ::GetCurrentThreadId() );1017if (! prevKbdHook) {1018lastError = ::GetLastError();1019}1020}1021return TRUE;10221023case cMonitorTheSameEventsAsJAWS:1024/*1025Causes jaccessinspetor to monitor the same events as JAWS. Useful1026when testing to determine if a bug is specific to JAWS or if it can1027be reproduced in jaccessinspector as well.1028*/1029trackMouse = FALSE;1030trackMouseExited = FALSE;1031trackMouseClicked = FALSE;1032trackMousePressed = FALSE;1033trackMouseReleased = FALSE;1034trackFocus = TRUE;1035trackFocusLost = TRUE;1036trackCaret = FALSE;1037trackShutdown = FALSE;10381039trackMenuSelected = FALSE;1040trackMenuDeselected = FALSE;1041trackMenuCanceled = FALSE;10421043trackPopupVisible = FALSE;1044trackPopupInvisible = FALSE;1045trackPopupCanceled = FALSE;10461047trackPropertyNameChange = TRUE;1048trackPropertyDescriptionChange = TRUE;1049trackPropertyStateChange = TRUE;1050trackPropertyValueChange = TRUE;1051trackPropertySelectionChange = TRUE;1052trackPropertyTextChange = TRUE;1053trackPropertyCaretChange = TRUE;1054trackPropertyVisibleDataChange = FALSE;1055trackPropertyChildChange = TRUE;1056trackPropertyActiveDescendentChange = TRUE;1057trackPropertyTableModelChange = FALSE;10581059ApplyEventOptions(hWnd);10601061return TRUE;10621063case cMonitorAllEvents:1064/*1065Causes jaccessinspector to monitor all Java Events and all1066Accessibility Events.1067*/1068trackMouse = TRUE;1069trackMouseExited = TRUE;1070trackMouseClicked = TRUE;1071trackMousePressed = TRUE;1072trackMouseReleased = TRUE;1073trackFocus = TRUE;1074trackFocusLost = TRUE;1075trackCaret = TRUE;1076trackShutdown = TRUE;10771078trackMenuSelected = TRUE;1079trackMenuDeselected = TRUE;1080trackMenuCanceled = TRUE;10811082trackPopupVisible = TRUE;1083trackPopupInvisible = TRUE;1084trackPopupCanceled = TRUE;10851086trackPropertyNameChange = TRUE;1087trackPropertyDescriptionChange = TRUE;1088trackPropertyStateChange = TRUE;1089trackPropertyValueChange = TRUE;1090trackPropertySelectionChange = TRUE;1091trackPropertyTextChange = TRUE;1092trackPropertyCaretChange = TRUE;1093trackPropertyVisibleDataChange = TRUE;1094trackPropertyChildChange = TRUE;1095trackPropertyActiveDescendentChange = TRUE;1096trackPropertyTableModelChange = TRUE;10971098ApplyEventOptions(hWnd);10991100return TRUE;11011102case cFirstMessage:1103{1104const char * messageText = g_MessageHistory.GetFirstMessage ();1105if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {1106::SetDlgItemText( theDialogWindow, cjaccessinspectorText,1107messageText );1108}1109EnableMessageNavButtons();1110UpdateMessageNumber();1111return TRUE;1112}1113break;11141115case cPreviousMessage:1116{1117const char * messageText = g_MessageHistory.GetPreviousMessage ();1118if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {1119::SetDlgItemText( theDialogWindow, cjaccessinspectorText,1120messageText );1121}1122EnableMessageNavButtons();1123UpdateMessageNumber();1124return TRUE;1125}1126break;11271128case cNextMessage:1129{1130const char * messageText = g_MessageHistory.GetNextMessage ();1131if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {1132::SetDlgItemText( theDialogWindow, cjaccessinspectorText,1133messageText );1134}1135EnableMessageNavButtons();1136UpdateMessageNumber();1137return TRUE;1138}1139break;11401141case cLastMessage:1142{1143const char * messageText = g_MessageHistory.GetLastMessage();1144if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {1145::SetDlgItemText( theDialogWindow, cjaccessinspectorText,1146messageText );1147}1148EnableMessageNavButtons();1149UpdateMessageNumber();1150return TRUE;1151}1152break;11531154case cResetAllEvents:1155trackMouse = FALSE;1156trackMouseExited = FALSE;1157trackMouseClicked = FALSE;1158trackMousePressed = FALSE;1159trackMouseReleased = FALSE;1160trackFocus = FALSE;1161trackFocusLost = FALSE;1162trackCaret = FALSE;1163trackShutdown = FALSE;11641165trackMenuSelected = FALSE;1166trackMenuDeselected = FALSE;1167trackMenuCanceled = FALSE;11681169trackPopupVisible = FALSE;1170trackPopupInvisible = FALSE;1171trackPopupCanceled = FALSE;11721173trackPropertyNameChange = FALSE;1174trackPropertyDescriptionChange = FALSE;1175trackPropertyStateChange = FALSE;1176trackPropertyValueChange = FALSE;1177trackPropertySelectionChange = FALSE;1178trackPropertyTextChange = FALSE;1179trackPropertyCaretChange = FALSE;1180trackPropertyVisibleDataChange = FALSE;1181trackPropertyChildChange = FALSE;1182trackPropertyActiveDescendentChange = FALSE;1183trackPropertyTableModelChange = FALSE;11841185ApplyEventOptions(hWnd);11861187return TRUE;11881189case cGoToMessage:1190InitGoToMessageDialogBox(theInstance);1191break;11921193case cClearMessageHistory:1194g_MessageHistory.clear();1195::SetDlgItemText(theDialogWindow, cjaccessinspectorText, NULL);1196EnableMessageNavButtons();1197UpdateMessageNumber();1198break;1199}1200break;12011202case DISPLAY_INFO_MESSAGE:1203echoMouseObject();1204return TRUE;12051206case DISPLAY_HWND_INFO_MESSAGE:1207echoMouseHWNDObject();1208return TRUE;1209}12101211return FALSE;1212}12131214#define SaveOptionToRegistry(optionVar) { \1215SetValue = RegSetValueEx( hKey, #optionVar, 0, REG_DWORD, \1216(LPBYTE)(&optionVar), sizeof(DWORD)); \1217if ( ERROR_SUCCESS != SetValue ) { \1218++ failureCount; \1219} \1220}12211222BOOL SaveActiveEventOptionsToRegistry() {1223LONG CreateKey = ERROR_SUCCESS;1224HKEY hKey = NULL;1225DWORD Disposition = 0;12261227CreateKey = ::RegCreateKeyEx( HKEY_CURRENT_USER,1228jaccessinspectorOptionsRegistryKey, 0, 0, 0,1229KEY_READ|KEY_WRITE, 0, &hKey, &Disposition );1230if ( ( ERROR_SUCCESS != CreateKey ) || ( NULL == hKey ) ) {1231return FALSE;1232}12331234LONG SetValue = ERROR_SUCCESS;1235unsigned long failureCount = 0;12361237SaveOptionToRegistry(trackMouse);1238SaveOptionToRegistry(trackMouseExited);1239SaveOptionToRegistry(trackMouseClicked);1240SaveOptionToRegistry(trackMousePressed);1241SaveOptionToRegistry(trackMouseReleased);1242SaveOptionToRegistry(trackShutdown);1243SaveOptionToRegistry(trackFocus);1244SaveOptionToRegistry(trackFocusLost);1245SaveOptionToRegistry(trackCaret);1246SaveOptionToRegistry(trackMenuSelected);1247SaveOptionToRegistry(trackMenuDeselected);1248SaveOptionToRegistry(trackMenuCanceled);1249SaveOptionToRegistry(trackPopupVisible);1250SaveOptionToRegistry(trackPopupInvisible);1251SaveOptionToRegistry(trackPopupCanceled);1252SaveOptionToRegistry(trackPropertyNameChange);1253SaveOptionToRegistry(trackPropertyDescriptionChange);1254SaveOptionToRegistry(trackPropertyStateChange);1255SaveOptionToRegistry(trackPropertyValueChange);1256SaveOptionToRegistry(trackPropertySelectionChange);1257SaveOptionToRegistry(trackPropertyTextChange);1258SaveOptionToRegistry(trackPropertyCaretChange);1259SaveOptionToRegistry(trackPropertyVisibleDataChange);1260SaveOptionToRegistry(trackPropertyChildChange);1261SaveOptionToRegistry(trackPropertyActiveDescendentChange);1262SaveOptionToRegistry(trackPropertyTableModelChange);12631264::RegFlushKey(hKey);1265::RegCloseKey(hKey);12661267if ( 0 == failureCount ) {1268return TRUE;1269}1270return FALSE;1271}12721273#define ReadOptionFromRegistry(optionVar) { \1274Type = Value = 0; \1275ValueSize = sizeof(DWORD); \1276QueryValue = ::RegQueryValueEx( hKey, #optionVar, NULL, &Type, \1277(LPBYTE)(&Value), &ValueSize); \1278if ( ( ERROR_SUCCESS == QueryValue ) && ( REG_DWORD == Type ) ) { \1279optionVar = static_cast<BOOL>(Value); \1280} else { \1281++ failureCount; \1282} \1283}12841285BOOL ReadActiveEventOptionsFromRegistry() {12861287trackMouse = FALSE;1288trackMouseExited = FALSE;1289trackMouseClicked = FALSE;1290trackMousePressed = FALSE;1291trackMouseReleased = FALSE;12921293trackShutdown = FALSE;1294trackFocus = FALSE;1295trackFocusLost = FALSE;1296trackCaret = FALSE;1297trackMenuSelected = FALSE;1298trackMenuDeselected = FALSE;1299trackMenuCanceled = FALSE;1300trackPopupVisible = FALSE;1301trackPopupInvisible = FALSE;1302trackPopupCanceled = FALSE;13031304trackPropertyNameChange = FALSE;1305trackPropertyDescriptionChange = FALSE;1306trackPropertyStateChange = FALSE;1307trackPropertyValueChange = FALSE;1308trackPropertySelectionChange = FALSE;1309trackPropertyTextChange = FALSE;1310trackPropertyCaretChange = FALSE;1311trackPropertyVisibleDataChange = FALSE;1312trackPropertyChildChange = FALSE;1313trackPropertyActiveDescendentChange = FALSE;1314trackPropertyTableModelChange = FALSE;13151316LONG OpenKey = ERROR_SUCCESS;1317HKEY hKey = NULL;1318OpenKey = ::RegOpenKeyEx( HKEY_CURRENT_USER,1319jaccessinspectorOptionsRegistryKey, 0,1320KEY_READ, &hKey );1321if ( ( ERROR_SUCCESS != OpenKey ) || ( NULL == hKey ) ) {1322return FALSE;1323}13241325LONG QueryValue = ERROR_SUCCESS;1326unsigned long failureCount = 0;1327DWORD Type, Value, ValueSize;13281329ReadOptionFromRegistry(trackMouse);1330ReadOptionFromRegistry(trackMouseExited);1331ReadOptionFromRegistry(trackMouseClicked);1332ReadOptionFromRegistry(trackMousePressed);1333ReadOptionFromRegistry(trackMouseReleased);1334ReadOptionFromRegistry(trackShutdown);1335ReadOptionFromRegistry(trackFocus);1336ReadOptionFromRegistry(trackFocusLost);1337ReadOptionFromRegistry(trackCaret);1338ReadOptionFromRegistry(trackMenuSelected);1339ReadOptionFromRegistry(trackMenuDeselected);1340ReadOptionFromRegistry(trackMenuCanceled);1341ReadOptionFromRegistry(trackPopupVisible);1342ReadOptionFromRegistry(trackPopupInvisible);1343ReadOptionFromRegistry(trackPopupCanceled);1344ReadOptionFromRegistry(trackPropertyNameChange);1345ReadOptionFromRegistry(trackPropertyDescriptionChange);1346ReadOptionFromRegistry(trackPropertyStateChange);1347ReadOptionFromRegistry(trackPropertyValueChange);1348ReadOptionFromRegistry(trackPropertySelectionChange);1349ReadOptionFromRegistry(trackPropertyTextChange);1350ReadOptionFromRegistry(trackPropertyCaretChange);1351ReadOptionFromRegistry(trackPropertyVisibleDataChange);1352ReadOptionFromRegistry(trackPropertyChildChange);1353ReadOptionFromRegistry(trackPropertyActiveDescendentChange);1354ReadOptionFromRegistry(trackPropertyTableModelChange);13551356::RegCloseKey(hKey);13571358if ( 0 == failureCount ) {1359return TRUE;1360}1361return FALSE;1362}13631364#define APPLY_EVENT_OPTION(menuItem, optionVar, setFP, handler) \1365{ \1366if ( optionVar ) { \1367::CheckMenuItem(menu, menuItem, MF_BYCOMMAND | MF_CHECKED); \1368setFP (handler); \1369} else { \1370::CheckMenuItem(menu, menuItem, MF_BYCOMMAND | MF_UNCHECKED); \1371setFP (NULL); \1372} \1373}13741375void ApplyEventOptions (HWND hWnd) {13761377HMENU menu = ::GetMenu (hWnd);1378APPLY_EVENT_OPTION( cTrackMouseMenuItem, trackMouse, SetMouseEntered,1379HandleMouseEntered );1380APPLY_EVENT_OPTION( cTrackMouseExitedMenuItem, trackMouseExited,1381SetMouseExited, HandleMouseExited );1382APPLY_EVENT_OPTION( cTrackMouseClickedMenuItem, trackMouseClicked,1383SetMouseClicked, HandleMouseClicked );1384APPLY_EVENT_OPTION( cTrackMousePressedMenuItem, trackMousePressed,1385SetMousePressed, HandleMousePressed );1386APPLY_EVENT_OPTION( cTrackMouseReleasedMenuItem, trackMouseReleased,1387SetMouseReleased, HandleMouseReleased );13881389APPLY_EVENT_OPTION( cTrackShutdownMenuItem, trackShutdown, SetJavaShutdown,1390HandleJavaShutdown );1391APPLY_EVENT_OPTION( cTrackFocusMenuItem, trackFocus, SetFocusGained,1392HandleJavaFocusGained );1393APPLY_EVENT_OPTION( cTrackFocusLostMenuItem, trackFocusLost, SetFocusLost,1394HandleJavaFocusLost );1395APPLY_EVENT_OPTION( cTrackCaretMenuItem, trackCaret, SetCaretUpdate,1396HandleJavaCaretUpdate );13971398APPLY_EVENT_OPTION( cTrackMenuSelectedMenuItem, trackMenuSelected,1399SetMenuSelected, HandleMenuSelected );1400APPLY_EVENT_OPTION( cTrackMenuDeselectedMenuItem, trackMenuDeselected,1401SetMenuDeselected, HandleMenuDeselected );1402APPLY_EVENT_OPTION( cTrackMenuCanceledItem, trackMenuCanceled,1403SetMenuCanceled, HandleMenuCanceled );14041405APPLY_EVENT_OPTION( cTrackPopupBecomeVisibleMenuItem, trackPopupVisible,1406SetPopupMenuWillBecomeVisible,1407HandlePopupMenuWillBecomeVisible );1408APPLY_EVENT_OPTION( cTrackPopupBecomeInvisibleMenuItem, trackPopupInvisible,1409SetPopupMenuWillBecomeInvisible,1410HandlePopupMenuWillBecomeInvisible );1411APPLY_EVENT_OPTION( cTrackPopupCanceledItem, trackPopupCanceled,1412SetPopupMenuCanceled, HandlePopupMenuCanceled );14131414APPLY_EVENT_OPTION( cTrackPropertyNameItem, trackPropertyNameChange,1415SetPropertyNameChange, HandlePropertyNameChange );1416APPLY_EVENT_OPTION( cTrackPropertyDescriptionItem,1417trackPropertyDescriptionChange,1418SetPropertyDescriptionChange,1419HandlePropertyDescriptionChange );1420APPLY_EVENT_OPTION( cTrackPropertyStateItem, trackPropertyStateChange,1421SetPropertyStateChange, HandlePropertyStateChange );1422APPLY_EVENT_OPTION( cTrackPropertyValueItem, trackPropertyValueChange,1423SetPropertyValueChange, HandlePropertyValueChange );1424APPLY_EVENT_OPTION( cTrackPropertySelectionItem,1425trackPropertySelectionChange,1426SetPropertySelectionChange,1427HandlePropertySelectionChange);1428APPLY_EVENT_OPTION( cTrackPropertyTextItem, trackPropertyTextChange,1429SetPropertyTextChange, HandlePropertyTextChange );1430APPLY_EVENT_OPTION( cTrackPropertyCaretItem, trackPropertyCaretChange,1431SetPropertyCaretChange, HandlePropertyCaretChange );1432APPLY_EVENT_OPTION( cTrackPropertyVisibleDataItem,1433trackPropertyVisibleDataChange,1434SetPropertyVisibleDataChange,1435HandlePropertyVisibleDataChange );1436APPLY_EVENT_OPTION( cTrackPropertyChildItem, trackPropertyChildChange,1437SetPropertyChildChange, HandlePropertyChildChange );1438APPLY_EVENT_OPTION( cTrackPropertyActiveDescendentItem,1439trackPropertyActiveDescendentChange,1440SetPropertyActiveDescendentChange,1441HandlePropertyActiveDescendentChange );1442APPLY_EVENT_OPTION( cTrackPropertyTableModelChangeItem,1443trackPropertyTableModelChange,1444SetPropertyTableModelChange,1445HandlePropertyTableModelChange );14461447MaybeCheckMonitorTheSameEventsAsJAWS(menu);1448MaybeCheckMonitorAllEvents(menu);1449}14501451BOOL EnableDlgItem(HWND hDlg, int nIDDlgItem, BOOL bEnable) {1452HWND dlgItem = ::GetDlgItem(hDlg, nIDDlgItem);1453if ( NULL == dlgItem ) {1454return FALSE;1455}1456return ::EnableWindow (dlgItem, bEnable);1457}14581459void EnableMessageNavButtons() {1460HWND FocusWindow = ::GetFocus();1461int FocusCtrlID = ::GetDlgCtrlID(FocusWindow);1462BOOL DisabledFocusWindow = FALSE;1463if ( 0 == g_MessageHistory.GetMessageCount () ) {1464EnableDlgItem(theDialogWindow, cFirstMessage, FALSE);1465EnableDlgItem(theDialogWindow, cPreviousMessage, FALSE);1466EnableDlgItem(theDialogWindow, cMessageNumber, FALSE);1467EnableDlgItem(theDialogWindow, cNextMessage, FALSE);1468EnableDlgItem(theDialogWindow, cLastMessage, FALSE);1469} else if ( g_MessageHistory.IsFirstMessage () ) {1470EnableDlgItem(theDialogWindow, cFirstMessage, FALSE);1471EnableDlgItem(theDialogWindow, cPreviousMessage, FALSE);1472EnableDlgItem(theDialogWindow, cMessageNumber, TRUE);1473EnableDlgItem(theDialogWindow, cNextMessage, TRUE);1474EnableDlgItem(theDialogWindow, cLastMessage, TRUE);1475if ( ( cFirstMessage == FocusCtrlID ) ||1476( cPreviousMessage == FocusCtrlID ) ) {1477DisabledFocusWindow = TRUE;1478}1479} else if ( g_MessageHistory.IsLastMessage () ) {1480EnableDlgItem(theDialogWindow, cFirstMessage, TRUE);1481EnableDlgItem(theDialogWindow, cPreviousMessage, TRUE);1482EnableDlgItem(theDialogWindow, cMessageNumber, TRUE);1483EnableDlgItem(theDialogWindow, cNextMessage, FALSE);1484EnableDlgItem(theDialogWindow, cLastMessage, FALSE);14851486if ( ( cNextMessage == FocusCtrlID ) ||1487( cLastMessage == FocusCtrlID ) ) {1488DisabledFocusWindow = TRUE;1489}1490} else {1491EnableDlgItem(theDialogWindow, cFirstMessage, TRUE);1492EnableDlgItem(theDialogWindow, cPreviousMessage, TRUE);1493EnableDlgItem(theDialogWindow, cMessageNumber, TRUE);1494EnableDlgItem(theDialogWindow, cNextMessage, TRUE);1495EnableDlgItem(theDialogWindow, cLastMessage, TRUE);1496}14971498if ( DisabledFocusWindow ) {1499/*1500We just disabled the window that had the focus. Set focus to the1501cjaccessinspectorText window. Otherwise it will no longer be possible1502to tab through the controls in jaccessinspector.1503*/1504HWND jaccessinspectorText =1505::GetDlgItem(theDialogWindow, cjaccessinspectorText);1506if ( jaccessinspectorText ) {1507::SetFocus(jaccessinspectorText);1508}1509}1510}15111512void WINAPI AddToMessageHistory(const char * message) {1513g_MessageHistory.AddMessage(message);1514EnableMessageNavButtons();1515UpdateMessageNumber();1516}15171518BOOL UpdateMessageNumber () {1519HWND dlgItem = ::GetDlgItem(theDialogWindow, cMessageNumber);1520if ( NULL == dlgItem ) {1521return FALSE;1522}15231524size_t messageCount = g_MessageHistory.GetMessageCount();1525size_t messageNumber = g_MessageHistory.GetCurrentMessageIndex() + 1;1526char text [32] = {0};1527if ( 0 != messageCount ) {1528::_snprintf(text, sizeof(text), "%d of %d", (int)messageNumber,1529(int) messageCount);1530}1531return ::SetWindowText(dlgItem, text);1532}15331534INT_PTR CALLBACK GoToMessageDialogProc( HWND hDlg, UINT message, WPARAM wParam,1535LPARAM lParam ) {1536BOOL ret_val = FALSE;1537switch ( message ) {1538case WM_INITDIALOG:1539{1540/*1541This code to center the Go To Message dialog box in the1542jaccessinspector window was taken from1543<http://msdn.microsoft.com/en-us/library/ms644996(VS.85).aspx>.1544*/1545HWND hwndOwner = NULL;1546RECT rcOwner = { 0, 0, 0, 0 };1547RECT rc = { 0, 0, 0, 0 };1548RECT rcDlg = { 0, 0, 0, 0 };15491550// Get the owner window and dialog box rectangles.1551if ( NULL == (hwndOwner = GetParent(hDlg)) ) {1552hwndOwner = GetDesktopWindow();1553}15541555GetWindowRect(hwndOwner, &rcOwner);1556GetWindowRect(hDlg, &rcDlg);1557CopyRect(&rc, &rcOwner);15581559// Offset the owner and dialog box rectangles so that right and1560// bottom values represent the width and height, and then offset1561// the owner again to discard space taken up by the dialog box.1562OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);1563OffsetRect(&rc, -rc.left, -rc.top);1564OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);15651566// The new position is the sum of half the remaining space and the1567// owner's original position.1568SetWindowPos (hDlg,1569HWND_TOP,1570rcOwner.left + (rc.right / 2),1571rcOwner.top + (rc.bottom / 2),15720, 0, // Ignores size arguments.1573SWP_NOSIZE);1574}1575break;15761577case WM_COMMAND:1578switch ( LOWORD (wParam) ) {1579case IDOK:1580{1581size_t GoToMessageNumber = 0;1582BOOL Translated = FALSE;1583GoToMessageNumber = GetDlgItemInt( hDlg, IDC_MESSAGE_NUMBER_EDIT,1584&Translated, FALSE );1585EndDialog (hDlg, IDOK);1586theGoToDialogWindow = NULL;15871588if ( ( Translated ) && ( GoToMessageNumber > 0 ) ) {1589const char * messageText = NULL;1590if ( (GoToMessageNumber - 1) <1591g_MessageHistory.GetMessageCount() ) {1592messageText =1593g_MessageHistory.GetMessage(GoToMessageNumber - 1);1594} else if ( (GoToMessageNumber - 1) >=1595g_MessageHistory.GetMessageCount() ) {1596messageText = g_MessageHistory.GetLastMessage();1597}1598if ( ( NULL != messageText ) && ( 0 != messageText [0] ) ) {1599::SetDlgItemText( theDialogWindow, cjaccessinspectorText,1600messageText );1601}1602EnableMessageNavButtons();1603UpdateMessageNumber();1604}1605}1606break;1607case IDCANCEL:1608EndDialog(hDlg, IDCANCEL);1609theGoToDialogWindow = NULL;1610break;1611}1612break;1613}1614return ret_val;1615}16161617BOOL InitGoToMessageDialogBox (HANDLE hInstance) {1618theGoToDialogWindow = CreateDialog (1619(struct HINSTANCE__ *)hInstance, MAKEINTRESOURCE(IDD_GO_TO_MESSAGE),1620theDialogWindow, GoToMessageDialogProc);16211622if ( NULL == theGoToDialogWindow ) {1623return FALSE;1624}16251626ShowWindow (theGoToDialogWindow, SW_SHOW);1627return TRUE;1628}16291630BOOL ShouldCheckMonitorTheSameEventsAsJAWS () {1631if (1632( FALSE == trackMouse )1633&& ( FALSE == trackMouseExited )1634&& ( FALSE == trackMouseClicked )1635&& ( FALSE == trackMousePressed )1636&& ( FALSE == trackMouseReleased )1637&& ( TRUE == trackFocus )1638&& ( TRUE == trackFocusLost )1639&& ( FALSE == trackCaret )1640&& ( FALSE == trackShutdown )1641&& ( FALSE == trackMenuSelected )1642&& ( FALSE == trackMenuDeselected )1643&& ( FALSE == trackMenuCanceled )1644&& ( FALSE == trackPopupVisible )1645&& ( FALSE == trackPopupInvisible )1646&& ( FALSE == trackPopupCanceled )1647&& ( TRUE == trackPropertyNameChange )1648&& ( TRUE == trackPropertyDescriptionChange )1649&& ( TRUE == trackPropertyStateChange )1650&& ( TRUE == trackPropertyValueChange )1651&& ( TRUE == trackPropertySelectionChange )1652&& ( TRUE == trackPropertyTextChange )1653&& ( TRUE == trackPropertyCaretChange )1654&& ( FALSE == trackPropertyVisibleDataChange )1655&& ( TRUE == trackPropertyChildChange )1656&& ( TRUE == trackPropertyActiveDescendentChange )1657&& ( FALSE == trackPropertyTableModelChange )1658)1659{1660return TRUE;1661}16621663return FALSE;1664}16651666void MaybeCheckMonitorTheSameEventsAsJAWS(HMENU menu) {1667UINT uCheck = MF_BYCOMMAND | MF_UNCHECKED;1668if ( ShouldCheckMonitorTheSameEventsAsJAWS() ) {1669uCheck = MF_BYCOMMAND | MF_CHECKED;1670}1671::CheckMenuItem(menu, cMonitorTheSameEventsAsJAWS, uCheck);1672}16731674BOOL ShouldCheckMonitorAllEvents() {1675if (1676( TRUE == trackMouse )1677&& ( TRUE == trackMouseExited )1678&& ( TRUE == trackMouseClicked )1679&& ( TRUE == trackMousePressed )1680&& ( TRUE == trackMouseReleased )1681&& ( TRUE == trackFocus )1682&& ( TRUE == trackFocusLost )1683&& ( TRUE == trackCaret )1684&& ( TRUE == trackShutdown )1685&& ( TRUE == trackMenuSelected )1686&& ( TRUE == trackMenuDeselected )1687&& ( TRUE == trackMenuCanceled )1688&& ( TRUE == trackPopupVisible )1689&& ( TRUE == trackPopupInvisible )1690&& ( TRUE == trackPopupCanceled )1691&& ( TRUE == trackPropertyNameChange )1692&& ( TRUE == trackPropertyDescriptionChange )1693&& ( TRUE == trackPropertyStateChange )1694&& ( TRUE == trackPropertyValueChange )1695&& ( TRUE == trackPropertySelectionChange )1696&& ( TRUE == trackPropertyTextChange )1697&& ( TRUE == trackPropertyCaretChange )1698&& ( TRUE == trackPropertyVisibleDataChange )1699&& ( TRUE == trackPropertyChildChange )1700&& ( TRUE == trackPropertyActiveDescendentChange )1701&& ( TRUE == trackPropertyTableModelChange )1702)1703{1704return TRUE;1705}17061707return FALSE;1708}17091710void MaybeCheckMonitorAllEvents(HMENU menu) {1711UINT uCheck = MF_BYCOMMAND | MF_UNCHECKED;1712if ( ShouldCheckMonitorAllEvents() ) {1713uCheck = MF_BYCOMMAND | MF_CHECKED;1714}1715::CheckMenuItem(menu, cMonitorAllEvents, uCheck);1716}171717181719