1 | unit fVA508HiddenJawsMainWindow;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
---|
7 | Dialogs, Contnrs, ExtCtrls, ComObj, VA508AccessibilityConst, AppEvnts;
|
---|
8 |
|
---|
9 | type
|
---|
10 | TfrmVA508HiddenJawsMainWindow = class(TForm)
|
---|
11 | ReloadTimer: TTimer;
|
---|
12 | CloseINIFilesTimer: TTimer;
|
---|
13 | procedure FormCreate(Sender: TObject);
|
---|
14 | procedure FormDestroy(Sender: TObject);
|
---|
15 | procedure ReloadTimerTimer(Sender: TObject);
|
---|
16 | procedure CloseINIFilesTimerTimer(Sender: TObject);
|
---|
17 | private
|
---|
18 | FRootCaption: string;
|
---|
19 | FPostWindow: HWnd;
|
---|
20 | FCloseFilesEvent: TNotifyEvent;
|
---|
21 | FData: string;
|
---|
22 | FVariables: string;
|
---|
23 | FDataWindowPool: TList;
|
---|
24 | FDataWindows: TObjectList;
|
---|
25 | FComponentDataCallBackProc: TComponentDataRequestProc;
|
---|
26 | FConfigChangePending: boolean;
|
---|
27 | FConfigReloadProc: TConfigReloadProc;
|
---|
28 | procedure ConverAccelChars(var text: string);
|
---|
29 | protected
|
---|
30 | procedure WndProc(var Msg: TMessage); override;
|
---|
31 | public
|
---|
32 | procedure ConfigReloadNeeded;
|
---|
33 | procedure WriteData(VarName, Value: string);
|
---|
34 | procedure PostData;
|
---|
35 | procedure ResetINITimer(Event: TNotifyEvent);
|
---|
36 | property ConfigReloadProc: TConfigReloadProc read FConfigReloadProc write FConfigReloadProc;
|
---|
37 | property ComponentDataCallBackProc: TComponentDataRequestProc read FComponentDataCallBackProc write FComponentDataCallBackProc;
|
---|
38 | property ConfigChangePending: boolean read FConfigChangePending write FConfigChangePending;
|
---|
39 | end;
|
---|
40 |
|
---|
41 | var
|
---|
42 | frmVA508HiddenJawsMainWindow: TfrmVA508HiddenJawsMainWindow;
|
---|
43 |
|
---|
44 | implementation
|
---|
45 |
|
---|
46 | uses JAWSCommon, fVA508HiddenJawsDataWindow, VAUtils;
|
---|
47 |
|
---|
48 | {$R *.dfm}
|
---|
49 |
|
---|
50 | procedure TfrmVA508HiddenJawsMainWindow.CloseINIFilesTimerTimer(
|
---|
51 | Sender: TObject);
|
---|
52 | begin
|
---|
53 | CloseINIFilesTimer.Enabled := FALSE;
|
---|
54 | if assigned(FCloseFilesEvent) then
|
---|
55 | FCloseFilesEvent(Sender);
|
---|
56 | end;
|
---|
57 |
|
---|
58 | procedure TfrmVA508HiddenJawsMainWindow.ConfigReloadNeeded;
|
---|
59 | begin
|
---|
60 | ReloadTimer.Enabled := FALSE;
|
---|
61 | ReloadTimer.Enabled := TRUE;
|
---|
62 | FConfigChangePending := TRUE;
|
---|
63 | end;
|
---|
64 |
|
---|
65 | // MSAA messes up strings with & chars
|
---|
66 | procedure TfrmVA508HiddenJawsMainWindow.ConverAccelChars(var text: string);
|
---|
67 | var
|
---|
68 | i: integer;
|
---|
69 | convert: boolean;
|
---|
70 | begin
|
---|
71 | repeat
|
---|
72 | i := pos('&', text);
|
---|
73 | if i > 0 then
|
---|
74 | begin
|
---|
75 | convert := (i = length(text));
|
---|
76 | if not convert then
|
---|
77 | convert := not (text[i+1] in ['A'..'Z','a'..'z','0'..'9']);
|
---|
78 | delete(text,i,1);
|
---|
79 | if convert then
|
---|
80 | insert(' and ', text, i);
|
---|
81 | end;
|
---|
82 | until i = 0;
|
---|
83 | end;
|
---|
84 |
|
---|
85 | procedure TfrmVA508HiddenJawsMainWindow.FormCreate(Sender: TObject);
|
---|
86 | begin
|
---|
87 | ErrorCheckClassName(Self, DLL_MAIN_WINDOW_CLASS);
|
---|
88 | FRootCaption := DLL_WINDOW_TITLE;
|
---|
89 | Caption := FRootCaption;
|
---|
90 | FDataWindowPool := TList.Create;
|
---|
91 | FDataWindows := TObjectList.Create;
|
---|
92 | end;
|
---|
93 |
|
---|
94 | procedure TfrmVA508HiddenJawsMainWindow.FormDestroy(Sender: TObject);
|
---|
95 | begin
|
---|
96 | FreeAndNil(FDataWindowPool);
|
---|
97 | FreeAndNil(FDataWindows);
|
---|
98 | end;
|
---|
99 |
|
---|
100 | procedure TfrmVA508HiddenJawsMainWindow.ReloadTimerTimer(Sender: TObject);
|
---|
101 | begin
|
---|
102 | ReloadTimer.Enabled := FALSE;
|
---|
103 | if assigned(FConfigReloadProc) then
|
---|
104 | FConfigReloadProc;
|
---|
105 | FConfigChangePending := FALSE;
|
---|
106 | end;
|
---|
107 |
|
---|
108 | procedure TfrmVA508HiddenJawsMainWindow.ResetINITimer(Event: TNotifyEvent);
|
---|
109 | begin
|
---|
110 | FCloseFilesEvent := Event;
|
---|
111 | CloseINIFilesTimer.Enabled := FALSE;
|
---|
112 | CloseINIFilesTimer.Enabled := TRUE;
|
---|
113 | end;
|
---|
114 |
|
---|
115 | // data is in 2 strings
|
---|
116 | // list of variable names
|
---|
117 | // list of data
|
---|
118 | procedure TfrmVA508HiddenJawsMainWindow.WriteData(VarName, Value: string);
|
---|
119 | var
|
---|
120 | offset, len: integer;
|
---|
121 | begin
|
---|
122 | ConverAccelChars(Value);
|
---|
123 | len := length(Value);
|
---|
124 | if len > 0 then
|
---|
125 | begin
|
---|
126 | offset := length(FData);
|
---|
127 | FData := FData + Value;
|
---|
128 | end
|
---|
129 | else
|
---|
130 | offset := 0;
|
---|
131 | FVariables := FVariables + DLL_WINDOW_DELIM + VarName + DLL_WINDOW_OFFSET +
|
---|
132 | IntToStr(offset) + DLL_WINDOW_LENGTH + IntToStr(len);
|
---|
133 | end;
|
---|
134 |
|
---|
135 | // output
|
---|
136 | // caption:[next window handle]:varlen:var=offset,length:var=offset,len:data
|
---|
137 | // varlen = from first to last :
|
---|
138 |
|
---|
139 | procedure TfrmVA508HiddenJawsMainWindow.PostData;
|
---|
140 | var
|
---|
141 | DataWindow, LastWindow: TfrmVA508HiddenJawsDataWindow;
|
---|
142 | Data, Output, RootOutput: string;
|
---|
143 | Done, UpdateLastWindow: boolean;
|
---|
144 | DataLen, Len, HandleIdx, AllowedChars, StartIndex: integer;
|
---|
145 |
|
---|
146 | procedure GetDataWindow;
|
---|
147 | var
|
---|
148 | idx: integer;
|
---|
149 | begin
|
---|
150 | if assigned(DataWindow) then
|
---|
151 | LastWindow := DataWindow;
|
---|
152 | if FDataWindowPool.Count > 0 then
|
---|
153 | begin
|
---|
154 | idx := FDataWindowPool.Count-1;
|
---|
155 | DataWindow := TfrmVA508HiddenJawsDataWindow(FDataWindowPool[idx]);
|
---|
156 | FDataWindowPool.Delete(idx);
|
---|
157 | end
|
---|
158 | else
|
---|
159 | begin
|
---|
160 | DataWindow := TfrmVA508HiddenJawsDataWindow.Create(Self);
|
---|
161 | FDataWindows.Add(DataWindow);
|
---|
162 | DataWindow.HandleNeeded;
|
---|
163 | Application.ProcessMessages;
|
---|
164 | end;
|
---|
165 | if FPostWindow = 0 then
|
---|
166 | FPostWindow := DataWindow.Handle;
|
---|
167 | end;
|
---|
168 |
|
---|
169 | begin
|
---|
170 | LastWindow := nil;
|
---|
171 | DataWindow := nil;
|
---|
172 | FVariables := FVariables + DLL_WINDOW_DELIM;
|
---|
173 | Len := length(FVariables);
|
---|
174 | Data := IntToStr(Len) + FVariables + FData;
|
---|
175 | DataLen := length(Data) + 1;
|
---|
176 | // Format = header : next window handle : data
|
---|
177 | RootOutput := FRootCaption + DLL_WINDOW_DELIM + DLL_WINDOW_DELIM;
|
---|
178 | HandleIdx := length(RootOutput);
|
---|
179 | AllowedChars := DLL_CAPTION_LIMIT - Length(RootOutput);
|
---|
180 | StartIndex := 1;
|
---|
181 | UpdateLastWindow := FALSE;
|
---|
182 | repeat
|
---|
183 | Done := TRUE;
|
---|
184 | GetDataWindow;
|
---|
185 | if UpdateLastWindow then
|
---|
186 | begin
|
---|
187 | Output := LastWindow.Caption;
|
---|
188 | insert(IntToStr(DataWindow.handle), Output, HandleIdx);
|
---|
189 | LastWindow.Caption := Output;
|
---|
190 | UpdateLastWindow := FALSE;
|
---|
191 | end;
|
---|
192 | Len := DataLen - StartIndex;
|
---|
193 | Output := RootOutput + copy(Data, StartIndex, AllowedChars);
|
---|
194 | DataWindow.Caption := Output;
|
---|
195 | if Len > AllowedChars then
|
---|
196 | begin
|
---|
197 | UpdateLastWindow := TRUE;
|
---|
198 | Done := FALSE;
|
---|
199 | inc(startIndex, AllowedChars);
|
---|
200 | end;
|
---|
201 | until Done;
|
---|
202 | end;
|
---|
203 |
|
---|
204 | procedure TfrmVA508HiddenJawsMainWindow.WndProc(var Msg: TMessage);
|
---|
205 | var
|
---|
206 | i: integer;
|
---|
207 | data: string;
|
---|
208 | begin
|
---|
209 | if Msg.Msg = MessageID then
|
---|
210 | begin
|
---|
211 | Msg.Result := 1;
|
---|
212 | data := caption;
|
---|
213 | try
|
---|
214 | // make sure Delphi has finished creating the form. If we dont, JAWS can detect the
|
---|
215 | // window before Delphi has finished creating it - resulting in an access violation
|
---|
216 | if assigned(Self) then
|
---|
217 | begin
|
---|
218 | try
|
---|
219 | if assigned(FComponentDataCallBackProc) then
|
---|
220 | begin
|
---|
221 | FPostWindow := 0;
|
---|
222 | FData := '';
|
---|
223 | FVariables := '';
|
---|
224 | FDataWindowPool.Assign(FDataWindows);
|
---|
225 | try
|
---|
226 | FComponentDataCallBackProc(Msg.WParam, Msg.LParam);
|
---|
227 | except
|
---|
228 | end;
|
---|
229 | // clean up unused windows
|
---|
230 | for i := 0 to FDataWindowPool.Count - 1 do
|
---|
231 | TfrmVA508HiddenJawsDataWindow(FDataWindowPool[i]).Caption := '';
|
---|
232 | SendReturnValue(Handle, FPostWindow);
|
---|
233 | end;
|
---|
234 | except
|
---|
235 | end;
|
---|
236 | end;
|
---|
237 | finally
|
---|
238 | if data = caption then
|
---|
239 | begin
|
---|
240 | SendReturnValue(Handle, 0);
|
---|
241 | end;
|
---|
242 | end;
|
---|
243 | end
|
---|
244 | else
|
---|
245 | inherited WndProc(Msg);
|
---|
246 | end;
|
---|
247 |
|
---|
248 | end.
|
---|