4
Description : Contains all functions for the Tk extension of flash windows
5
This is an extension for Tk only for windows, it will make the window
6
flash in the taskbar until it gets focus.
11
winflash - Flashes the window taskbar and caption of a toplevel widget
14
winflash window_name ?option value option value...?
17
This command will make the taskbar of a toplevel window and it's caption flash under windows,
18
the window_name argument must be the tk pathname of a toplevel widget (.window for example)
19
The options (abbrevations allowed) are as follow :
22
The -state option sets is used to make the window flash or to make it stop flashing, a boolean
23
must follow the -state option, 0 to make it stop flashing, 1 to make it flash.
26
The -count option specifies the number of time the window must flash before stoping and keeping the
27
orange color. Use -1 to make it flash continuously (you then MUST use a winflash -state 0 to make it
28
stop, it won't stop even if it gets the focus.
31
The -interval option specifies the interval in ms between each flash, use 0 to take the default
35
The -tray option can be used to specify that you only want the taskbar to flash.
36
If not specified, the taskbar AND the title of the window will flash.
37
if you want only the tray to flash, use -caption 0
40
The -caption option can be used to specify that you only want the title of the window to flash
41
If you want only the title to flash, use -tray 0
44
This option is used to specify that the flashing should stop when any window of the application gets focus.
45
If not specified, the flashing will stop only when focus is on the flashing window.
49
Author : Youness El Alaoui (KaKaRoTo - kakaroto@users.sourceforge.net)
53
// Include the header file
58
Function : Tk_FlashWindow
60
Description : This is the function that does the whole job, it will flash the window as
61
given in it's argument
63
Arguments : ClienData clientdata : who knows what's that used for :P
64
anways, it's set to NULL and it's not used
66
Tcl_Interp *interp : This is the interpreter that called this function
67
it will be used to get some info about the window used
69
int objc : This is the number of arguments given to the function
71
Tcl_Obj *CONST objv[] : This is the array that contains all arguments given to
74
Return value : TCL_OK in case everything is ok, or TCL_ERROR in case there is an error
76
Comments : hummmm... not much, it's simple :)
79
static int Tk_FlashWindow (ClientData clientData,
82
Tcl_Obj *CONST objv[]) {
85
// We declare our variables, we need one for every intermediate token we get,
86
// so we can verify if one of the function calls returned NULL
105
// We verify the arguments, we must have one arg, not more
107
Tcl_AppendResult (interp, "Wrong number of args.\nShould be \"winflash window_name \?option value option value...\?\"" , (char *) NULL);
112
// Get the first argument string (object name) and check it
113
win=Tcl_GetStringFromObj(objv[1], NULL);
115
// We check if the pathname is valid, this means it must beguin with a "."
116
// the strncmp(win, ".", 1) is used to compare the first char of the pathname
118
if (strncmp(win,".",1)) {
119
Tcl_AppendResult (interp, "Bad window path name : ",
120
Tcl_GetStringFromObj(objv[1], NULL) , (char *) NULL);
125
// We then get each more arguments if they exist, and check their validity, and then change variables depending on options
126
// We stop one arg before the last arg, because we parse 2 at a time, and we stop when the return value of Tcl_GetBooleanFromObj
127
// or Tcl_GetIntFromObj returns TCL_ERROR
128
for (int i = 2; i < objc -1 && ret != TCL_ERROR; i++) {
129
// We get the option and the first two chars to compare with (to allow abbrevations)
130
option = Tcl_GetStringFromObj(objv[i], &optlength);
131
if ( strncmp(option, "-", 1) ){
132
Tcl_AppendResult (interp, "Invalid option : ",
133
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
136
if ( optlength < 2 ) {
140
if ( optlength == 2 ){
149
// Switch, depending on first letter of the option (after the -)
153
// We compare each char of the option with "-state"
154
strcpy(opt,"-state");
155
// If option is longer than -state, then it's not valid (also avoids bug in the for statement below
156
if ( optlength > 6) {
157
Tcl_AppendResult (interp, "Invalid option : ",
158
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
161
// For each char of the option, compare it.
162
for ( int j = 2; j < optlength ; j++) {
163
if ( option[j] != opt[j]) {
164
Tcl_AppendResult (interp, "Invalid option : ",
165
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
170
// Retreive the value
171
ret = Tcl_GetBooleanFromObj(interp, objv[++i],&state);
174
// The -count and -caption options
177
strcpy(opt,"-count");
179
// comments are the same as in the -state option
180
if ( optlength > 6) {
181
Tcl_AppendResult (interp, "Invalid option : ",
182
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
185
for ( int j = 2; j < optlength ; j++) {
186
if ( option[j] != opt[j]) {
187
Tcl_AppendResult (interp, "Invalid option : ",
188
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
193
ret = Tcl_GetIntFromObj(interp, objv[++i],&count);
194
} else if (opt2 == 'a' ) {
195
// The -caption option
196
strcpy(opt,"-caption");
197
if ( optlength > 8) {
198
Tcl_AppendResult (interp, "Invalid option : ",
199
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
202
for ( int j = 2; j < optlength ; j++) {
203
if ( option[j] != opt[j]) {
204
Tcl_AppendResult (interp, "Invalid option : ",
205
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
210
ret = Tcl_GetBooleanFromObj(interp, objv[++i],&caption);
212
// If the second letter is not 'o' or 'a' (for count/caption), bring error
213
Tcl_AppendResult (interp, "Invalid option : ",
214
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
219
// The -interval option
220
strcpy(opt,"-interval");
221
if ( optlength > 9) {
222
Tcl_AppendResult (interp, "Invalid option : ",
223
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
226
for ( int j = 2; j < optlength ; j++) {
227
if ( option[j] != opt[j]) {
228
Tcl_AppendResult (interp, "Invalid option : ",
229
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
234
ret = Tcl_GetIntFromObj(interp, objv[++i],&interval);
239
if ( optlength > 5) {
240
Tcl_AppendResult (interp, "Invalid option : ",
241
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
244
for ( int j = 2; j < optlength ; j++) {
245
if ( option[j] != opt[j]) {
246
Tcl_AppendResult (interp, "Invalid option : ",
247
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
252
ret = Tcl_GetBooleanFromObj(interp, objv[++i],&tray);
255
// The -appfocus option
256
strcpy(opt,"-appfocus");
257
if ( optlength > 9) {
258
Tcl_AppendResult (interp, "Invalid option : ",
259
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
262
for ( int j = 2; j < optlength ; j++) {
263
if ( option[j] != opt[j]) {
264
Tcl_AppendResult (interp, "Invalid option : ",
265
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
270
ret = Tcl_GetBooleanFromObj(interp, objv[++i],&appfocus);
273
// If no valid option, bring error
274
Tcl_AppendResult (interp, "Invalid option : ",
275
Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
281
// If one of the Tcl_Get*FromObj returned error, then bring error
282
if ( ret == TCL_ERROR ) return TCL_ERROR;
284
// If we stopped before the end, then there is an option without value, bring error.
286
Tcl_AppendResult (interp, "Option \"",
287
Tcl_GetStringFromObj(objv[i], NULL), "\" don't have any value", (char *) NULL);
291
// Here we ge the long pathname (tk window name), from the short pathname, using the MainWindow from the interpreter
292
tkwin = Tk_NameToWindow(interp, win, Tk_MainWindow(interp));
295
if ( tkwin == NULL) return TCL_ERROR;
297
// We then get the windowId (the X token) of the window, from it's long pathname
298
window = Tk_WindowId(tkwin);
301
if ( window == NULL ) {
302
Tcl_AppendResult (interp, "error while processing WindowId : Window probably not viewable", (char *) NULL);
306
// We then get the HWND (Window Handler) from the X token.
307
hwnd = Tk_GetHWND(window);
310
if ( hwnd == NULL ) {
311
Tcl_AppendResult (interp, "error while processing GetHWND ", (char *) NULL);
315
// We get it's parent window handler. This is a bit tricky, in fact, in Tk, toplevel windows are
316
// just widgets embeded in a container, and we need to get that container's HWND to make it flash
317
hwnd = GetParent(hwnd);
319
if ( hwnd == NULL || ! IsWindow(hwnd)) {
320
Tcl_AppendResult(interp, "Unknown error, pathname is not a valid toplevel window" , (char *) NULL);
325
// We set our structure and fill it properly
328
fInfo.cbSize = sizeof(fInfo);
329
fInfo.uCount = count; // number of times to flash
330
fInfo.dwTimeout = interval; //Time out between flashes, 0 means default
332
// The FLASHW_STOP flag is equal to 0, so if state is set to false, the flag is FLASHW_STOP, else, it has one of the
334
fInfo.dwFlags = FLASHW_STOP;
337
// depending on options, fill the flag variable
340
fInfo.dwFlags |= FLASHW_TRAY;
343
fInfo.dwFlags |= FLASHW_CAPTION;
346
fInfo.dwFlags |= FLASHW_TIMERNOFG;
350
// Finally call the Windows API, and it's done :D
351
FlashWindowEx ( &fInfo);
359
Function : Flash_Init
361
Description : The Init function that will be called when the extension is loaded to your tk shell
363
Arguments : Tcl_Interp *interp : This is the interpreter from which the load was made and to
364
which we'll add the new command
367
Return value : TCL_OK in case everything is ok, or TCL_ERROR in case there is an error (Tk version < 8.3)
369
Comments : hummmm... not much, it's simple :)
372
int Flash_Init (Tcl_Interp *interp ) {
374
//Check TK version is 8.0 or higher
375
if (Tk_InitStubs(interp, "8.3", 0) == NULL) {
380
// Create the new command "winflash" linked to the Tk_FlashWindow function with a NULL clientdata and no deleteproc
381
Tcl_CreateObjCommand(interp, "winflash", Tk_FlashWindow,
382
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);