feisty meow concerns codebase 2.140
zing_window.cpp
Go to the documentation of this file.
1/*****************************************************************************\
2* *
3* Name : zing_window *
4* Author : Chris Koeritz *
5* *
6* Purpose: *
7* *
8* Sends a message to a window. The window can either be located by its *
9* unique window handle (if known) or by its exact title. There is currently *
10* no wildcard matching supported to find other types of titles. If the *
11* window is located, then it is sent a windows message of your choice. You *
12* can additionally add the wparam and lparam integers that get sent with *
13* the message. This is useful for shutting windows down gracefully by *
14* sending them the WM_CLOSE message. *
15* *
16*******************************************************************************
17* Copyright (c) 2000-$now By Author. This program is free software; you can *
18* redistribute it and/or modify it under the terms of the GNU General Public *
19* License as published by the Free Software Foundation; either version 2 of *
20* the License or (at your option) any later version. This is online at: *
21* http://www.fsf.org/copyleft/gpl.html *
22* Please send any updates to: fred@gruntose.com *
23\*****************************************************************************/
24
26#include <basis/guards.h>
27#include <basis/astring.h>
28
31#include <filesystem/filename.h>
35#include <unit_test/unit_base.h>
36
37#include <stdio.h>
38
39//hmmm: this should be based on unit_base and be a real test.
40
41using namespace application;
42using namespace basis;
43//using namespace configuration;
44//using namespace mathematics;
45using namespace filesystem;
46using namespace loggers;
47//using namespace processes;
48//using namespace structures;
49//using namespace textual;
50using namespace timely;
51using namespace unit_test;
52
53#undef LOG
54//#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s))
55
56#ifdef __WIN32__
57
58window_handle matching_window = NULL_POINTER;
59astring window_name_sought;
60
61BOOL CALLBACK zingers_enum_proc(window_handle hwnd, LPARAM lParam)
62{
63 const int MAX_TITLE = 1024;
64 flexichar win_name[MAX_TITLE + 8]; // add a little for good luck.
65 int chars = GetWindowText(hwnd, win_name, MAX_TITLE - 1);
66 if (chars > 0) {
67 // see if the current window matches what we're looking for.
68 if (astring(from_unicode_temp(win_name)).ifind(window_name_sought) >= 0) {
69 matching_window = hwnd;
70 return false; // don't keep going.
71 }
72 }
73 return true; // haven't found it yet.
74}
75
76int main(int argc, char *argv[])
77{
79 command_line cmds(argc, argv);
80 if ( (cmds.entries() < 2)
81 || (cmds.get(0).type() != command_parameter::VALUE) ) {
82 out.log(cmds.program_name().basename().raw() + " usage:\n"
83 "This takes at least two parameters. The first parameter is a window\n"
84 "handle that is to be contacted. Alternatively, the first parameter\n"
85 "can be the title of the window. The second parameter is a numerical\n"
86 "event that the window is to be zinged with. Zinging is synonymous\n"
87 "here with \"sending a message to the window\". Depending on the\n"
88 "message chosen, the window will behave in various different ways.\n"
89 "If there are a third or fourth parameter, then these are taken as\n"
90 "the extra data to send in the PostMessage call for zinging.");
91 out.log(a_sprintf("\nExample windows message values:\n\t"
92 "WM_CLOSE = %d\n\tWM_PAINT = %d", WM_CLOSE, WM_PAINT));
93 return 1;
94 }
95
96 astring junk_text = cmds.get(0).text();
97 bool saw_hex_code = false;
98 if (junk_text.begins("0x")) {
99 // we have a hex code. we will key off of that, which assumes that there
100 // is never going to be an important window whose title starts with that.
101 saw_hex_code = true;
102 }
103 int temp_handle = 0;
104 if (saw_hex_code) {
105 sscanf(junk_text.s(), "%lx", &temp_handle);
106 } else {
107 sscanf(junk_text.s(), "%ld", &temp_handle);
108 }
109
110//hmmm: this code is not so good for 64 bit.
111 #pragma warning(disable : 4312)
112 window_handle handle = (window_handle)temp_handle;
113
114 // we'll set the flag below if we find anything besides numbers in the
115 // window handle string.
116 bool has_alpha = false;
117 if (!saw_hex_code) {
118 // we only check for alphabetical characters if we didn't already
119 // decide the parameter had a hex code in front making it a number.
120 for (int i = 0; i < junk_text.length(); i++) {
121 if ( (junk_text[i] < '0') || (junk_text[i] > '9') ) {
122 has_alpha = true;
123 break;
124 }
125 }
126 }
127 if (has_alpha) {
128 // reset our match first.
129 matching_window = NULL_POINTER;
130 window_name_sought = junk_text;
131//out.log("saw non-numbers in handle, trying as name.");
132 // enumerate the windows looking for a match.
133 EnumWindows(zingers_enum_proc, 0);
134 if (!matching_window) {
135 out.log("no matching window could be found. ignoring request.");
136 return 1;
137 }
138//out.log("found matching window handle...");
139 handle = matching_window;
140 }
141
142 junk_text = cmds.get(1).text();
143 ULONG event = (ULONG)junk_text.convert(0);
144 ULONG p1 = 0;
145 ULONG p2 = 0;
146 if (cmds.entries() >= 3) {
147 junk_text = cmds.get(2).text();
148 p1 = (ULONG)junk_text.convert(0);
149 }
150 if (cmds.entries() >= 4) {
151 junk_text = cmds.get(3).text();
152 p2 = (ULONG)junk_text.convert(0);
153 }
154
155 if (!handle || !event) {
156 out.log("the window handle or the event was invalid. ignoring request.");
157 return 1;
158 }
159
160 PostMessage(handle, event, p1, p2);
161
162 out.log(a_sprintf("posted at 0x%lx the zing (%u %u %u)", handle, event,
163 p1, p2));
164
165 return 0;
166}
167#else
168// non-windows implementation is a no-op.
169int main(int argc, char *argv[])
170{
171 return 0;
172}
173#endif
174
175#ifdef __BUILD_STATIC_APPLICATION__
176 // static dependencies found by buildor_gen_deps.sh:
177 #include <algorithms/sorts.cpp>
182 #include <basis/astring.cpp>
184 #include <basis/environment.cpp>
185 #include <basis/guards.cpp>
186 #include <basis/mutex.cpp>
187 #include <basis/utf_conversion.cpp>
195 #include <filesystem/directory.cpp>
196 #include <filesystem/filename.cpp>
197 #include <loggers/combo_logger.cpp>
200 #include <loggers/file_logger.cpp>
203 #include <structures/checksums.cpp>
210 #include <textual/parser_bits.cpp>
213 #include <timely/earth_time.cpp>
214 #include <timely/time_stamp.cpp>
215 #include <unit_test/unit_base.cpp>
216#endif // __BUILD_STATIC_APPLICATION__
217
a_sprintf is a specialization of astring that provides printf style support.
Definition astring.h:440
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
Definition astring.h:113
virtual char get(int index) const
a constant peek at the string's internals at the specified index.
Definition astring.cpp:138
int convert(int default_value) const
Converts the string into a corresponding integer.
Definition astring.cpp:760
bool begins(const astring &maybe_prefix) const
Returns true if "this" string begins with "maybe_prefix".
Definition astring.h:178
int length() const
Returns the current length of the string.
Definition astring.cpp:132
virtual basis::outcome log(const basis::base_string &info, int filter)
sends the string "info" to the standard output device.
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
Provides macros that implement the 'main' program of an application.
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
char flexichar
Definition definitions.h:58
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
#include <time.h>
Useful support functions for unit testing, especially within hoople.
Definition unit_base.cpp:35
Support for unicode builds.
void * window_handle
int main(int argc, char *argv[])