You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.1 KiB
131 lines
4.1 KiB
# |
|
# Copyright (c) 2012 Ashok P. Nadkarni |
|
# All rights reserved. |
|
# |
|
# See the file LICENSE for license |
|
|
|
# Contains common windowing and notification infrastructure |
|
|
|
namespace eval twapi { |
|
variable null_hwin "" |
|
|
|
# Windows messages that are directly accessible from script. These |
|
# are handled by the default notifications window and passed to |
|
# the twapi::_script_wm_handler. These messages must be in the |
|
# range (1056 = 1024+32) - (1024+32+31) (see twapi_wm.h) |
|
variable _wm_script_msgs |
|
array set _wm_script_msgs { |
|
TASKBAR_RESTART 1031 |
|
NOTIFY_ICON_CALLBACK 1056 |
|
} |
|
proc _get_script_wm {tok} { |
|
variable _wm_script_msgs |
|
return $_wm_script_msgs($tok) |
|
} |
|
} |
|
|
|
# Backward compatibility aliases |
|
interp alias {} twapi::GetWindowLong {} twapi::GetWindowLongPtr |
|
interp alias {} twapi::SetWindowLong {} twapi::SetWindowLongPtr |
|
|
|
# Return the long value at the given index |
|
# This is a raw function, and should generally be used only to get |
|
# non-system defined indices |
|
proc twapi::get_window_long {hwin index} { |
|
return [GetWindowLongPtr $hwin $index] |
|
} |
|
|
|
# Set the long value at the given index and return the previous value |
|
# This is a raw function, and should generally be used only to get |
|
# non-system defined indices |
|
proc twapi::set_window_long {hwin index val} { |
|
set oldval [SetWindowLongPtr $hwin $index $val] |
|
} |
|
|
|
# Set the user data associated with a window. Returns the previous value |
|
proc twapi::set_window_userdata {hwin val} { |
|
# GWL_USERDATA -> -21 |
|
return [SetWindowLongPtr $hwin -21 $val] |
|
} |
|
|
|
# Attaches to the thread queue of the thread owning $hwin and executes |
|
# script in the caller's scope |
|
proc twapi::_attach_hwin_and_eval {hwin script} { |
|
set me [GetCurrentThreadId] |
|
set hwin_tid [lindex [GetWindowThreadProcessId $hwin] 0] |
|
if {$hwin_tid == 0} { |
|
error "Window $hwin does not exist or could not get its thread owner" |
|
} |
|
|
|
# Cannot (and no need to) attach to oneself so just exec script directly |
|
if {$me == $hwin_tid} { |
|
return [uplevel 1 $script] |
|
} |
|
|
|
trap { |
|
if {![AttachThreadInput $me $hwin_tid 1]} { |
|
error "Could not attach to thread input for window $hwin" |
|
} |
|
set result [uplevel 1 $script] |
|
} finally { |
|
AttachThreadInput $me $hwin_tid 0 |
|
} |
|
|
|
return $result |
|
} |
|
|
|
proc twapi::_register_script_wm_handler {msg cmdprefix {overwrite 0}} { |
|
variable _wm_registrations |
|
|
|
# Ensure notification window exists |
|
twapi::Twapi_GetNotificationWindow |
|
|
|
# The incr ensures decimal format |
|
# The lrange ensure proper list format |
|
if {$overwrite} { |
|
set _wm_registrations([incr msg 0]) [list [lrange $cmdprefix 0 end]] |
|
} else { |
|
lappend _wm_registrations([incr msg 0]) [lrange $cmdprefix 0 end] |
|
} |
|
} |
|
|
|
proc twapi::_unregister_script_wm_handler {msg cmdprefix} { |
|
variable _wm_registrations |
|
|
|
# The incr ensures decimal format |
|
incr msg 0 |
|
# The lrange ensure proper list format |
|
if {[info exists _wm_registrations($msg)]} { |
|
set _wm_registrations($msg) [lsearch -exact -inline -not -all $_wm_registrations($msg) [lrange $cmdprefix 0 end]] |
|
} |
|
} |
|
|
|
# Handles notifications from the common window for script level windows |
|
# messages (see win.c) |
|
proc twapi::_script_wm_handler {msg wparam lparam msgpos ticks} { |
|
variable _wm_registrations |
|
|
|
set code 0 |
|
if {[info exists _wm_registrations($msg)]} { |
|
foreach handler $_wm_registrations($msg) { |
|
set code [catch {uplevel #0 [linsert $handler end $msg $wparam $lparam $msgpos $ticks]} msg] |
|
switch -exact -- $code { |
|
1 { |
|
# TBD - should remaining handlers be called even on error ? |
|
after 0 [list error $msg $::errorInfo $::errorCode] |
|
break |
|
} |
|
3 { |
|
break; # Ignore remaining handlers |
|
} |
|
default { |
|
# Keep going |
|
} |
|
} |
|
} |
|
} else { |
|
# TBD - debuglog - no handler for $msg |
|
} |
|
|
|
return |
|
}
|
|
|