metasm 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/BUGS +11 -0
- data/CREDITS +17 -0
- data/README +270 -0
- data/TODO +114 -0
- data/doc/code_organisation.txt +146 -0
- data/doc/const_missing.txt +16 -0
- data/doc/core_classes.txt +75 -0
- data/doc/feature_list.txt +53 -0
- data/doc/index.txt +59 -0
- data/doc/install_notes.txt +170 -0
- data/doc/style.css +3 -0
- data/doc/use_cases.txt +18 -0
- data/lib/metasm.rb +80 -0
- data/lib/metasm/arm.rb +12 -0
- data/lib/metasm/arm/debug.rb +39 -0
- data/lib/metasm/arm/decode.rb +167 -0
- data/lib/metasm/arm/encode.rb +77 -0
- data/lib/metasm/arm/main.rb +75 -0
- data/lib/metasm/arm/opcodes.rb +177 -0
- data/lib/metasm/arm/parse.rb +130 -0
- data/lib/metasm/arm/render.rb +55 -0
- data/lib/metasm/compile_c.rb +1457 -0
- data/lib/metasm/dalvik.rb +8 -0
- data/lib/metasm/dalvik/decode.rb +196 -0
- data/lib/metasm/dalvik/main.rb +60 -0
- data/lib/metasm/dalvik/opcodes.rb +366 -0
- data/lib/metasm/decode.rb +213 -0
- data/lib/metasm/decompile.rb +2659 -0
- data/lib/metasm/disassemble.rb +2068 -0
- data/lib/metasm/disassemble_api.rb +1280 -0
- data/lib/metasm/dynldr.rb +1329 -0
- data/lib/metasm/encode.rb +333 -0
- data/lib/metasm/exe_format/a_out.rb +194 -0
- data/lib/metasm/exe_format/autoexe.rb +82 -0
- data/lib/metasm/exe_format/bflt.rb +189 -0
- data/lib/metasm/exe_format/coff.rb +455 -0
- data/lib/metasm/exe_format/coff_decode.rb +901 -0
- data/lib/metasm/exe_format/coff_encode.rb +1078 -0
- data/lib/metasm/exe_format/dex.rb +457 -0
- data/lib/metasm/exe_format/dol.rb +145 -0
- data/lib/metasm/exe_format/elf.rb +923 -0
- data/lib/metasm/exe_format/elf_decode.rb +979 -0
- data/lib/metasm/exe_format/elf_encode.rb +1375 -0
- data/lib/metasm/exe_format/macho.rb +827 -0
- data/lib/metasm/exe_format/main.rb +228 -0
- data/lib/metasm/exe_format/mz.rb +164 -0
- data/lib/metasm/exe_format/nds.rb +172 -0
- data/lib/metasm/exe_format/pe.rb +437 -0
- data/lib/metasm/exe_format/serialstruct.rb +246 -0
- data/lib/metasm/exe_format/shellcode.rb +114 -0
- data/lib/metasm/exe_format/xcoff.rb +167 -0
- data/lib/metasm/gui.rb +23 -0
- data/lib/metasm/gui/cstruct.rb +373 -0
- data/lib/metasm/gui/dasm_coverage.rb +199 -0
- data/lib/metasm/gui/dasm_decomp.rb +369 -0
- data/lib/metasm/gui/dasm_funcgraph.rb +103 -0
- data/lib/metasm/gui/dasm_graph.rb +1354 -0
- data/lib/metasm/gui/dasm_hex.rb +543 -0
- data/lib/metasm/gui/dasm_listing.rb +599 -0
- data/lib/metasm/gui/dasm_main.rb +906 -0
- data/lib/metasm/gui/dasm_opcodes.rb +291 -0
- data/lib/metasm/gui/debug.rb +1228 -0
- data/lib/metasm/gui/gtk.rb +884 -0
- data/lib/metasm/gui/qt.rb +495 -0
- data/lib/metasm/gui/win32.rb +3004 -0
- data/lib/metasm/gui/x11.rb +621 -0
- data/lib/metasm/ia32.rb +14 -0
- data/lib/metasm/ia32/compile_c.rb +1523 -0
- data/lib/metasm/ia32/debug.rb +193 -0
- data/lib/metasm/ia32/decode.rb +1167 -0
- data/lib/metasm/ia32/decompile.rb +564 -0
- data/lib/metasm/ia32/encode.rb +314 -0
- data/lib/metasm/ia32/main.rb +233 -0
- data/lib/metasm/ia32/opcodes.rb +872 -0
- data/lib/metasm/ia32/parse.rb +327 -0
- data/lib/metasm/ia32/render.rb +91 -0
- data/lib/metasm/main.rb +1193 -0
- data/lib/metasm/mips.rb +11 -0
- data/lib/metasm/mips/compile_c.rb +7 -0
- data/lib/metasm/mips/decode.rb +253 -0
- data/lib/metasm/mips/encode.rb +51 -0
- data/lib/metasm/mips/main.rb +72 -0
- data/lib/metasm/mips/opcodes.rb +443 -0
- data/lib/metasm/mips/parse.rb +51 -0
- data/lib/metasm/mips/render.rb +43 -0
- data/lib/metasm/os/gnu_exports.rb +270 -0
- data/lib/metasm/os/linux.rb +1112 -0
- data/lib/metasm/os/main.rb +1686 -0
- data/lib/metasm/os/remote.rb +527 -0
- data/lib/metasm/os/windows.rb +2027 -0
- data/lib/metasm/os/windows_exports.rb +745 -0
- data/lib/metasm/parse.rb +876 -0
- data/lib/metasm/parse_c.rb +3938 -0
- data/lib/metasm/pic16c/decode.rb +42 -0
- data/lib/metasm/pic16c/main.rb +17 -0
- data/lib/metasm/pic16c/opcodes.rb +68 -0
- data/lib/metasm/ppc.rb +11 -0
- data/lib/metasm/ppc/decode.rb +264 -0
- data/lib/metasm/ppc/decompile.rb +251 -0
- data/lib/metasm/ppc/encode.rb +51 -0
- data/lib/metasm/ppc/main.rb +129 -0
- data/lib/metasm/ppc/opcodes.rb +410 -0
- data/lib/metasm/ppc/parse.rb +52 -0
- data/lib/metasm/preprocessor.rb +1277 -0
- data/lib/metasm/render.rb +130 -0
- data/lib/metasm/sh4.rb +8 -0
- data/lib/metasm/sh4/decode.rb +336 -0
- data/lib/metasm/sh4/main.rb +292 -0
- data/lib/metasm/sh4/opcodes.rb +381 -0
- data/lib/metasm/x86_64.rb +12 -0
- data/lib/metasm/x86_64/compile_c.rb +1025 -0
- data/lib/metasm/x86_64/debug.rb +59 -0
- data/lib/metasm/x86_64/decode.rb +268 -0
- data/lib/metasm/x86_64/encode.rb +264 -0
- data/lib/metasm/x86_64/main.rb +135 -0
- data/lib/metasm/x86_64/opcodes.rb +118 -0
- data/lib/metasm/x86_64/parse.rb +68 -0
- data/misc/bottleneck.rb +61 -0
- data/misc/cheader-findpppath.rb +58 -0
- data/misc/hexdiff.rb +74 -0
- data/misc/hexdump.rb +55 -0
- data/misc/metasm-all.rb +13 -0
- data/misc/objdiff.rb +47 -0
- data/misc/objscan.rb +40 -0
- data/misc/pdfparse.rb +661 -0
- data/misc/ppc_pdf2oplist.rb +192 -0
- data/misc/tcp_proxy_hex.rb +84 -0
- data/misc/txt2html.rb +440 -0
- data/samples/a.out.rb +31 -0
- data/samples/asmsyntax.rb +77 -0
- data/samples/bindiff.rb +555 -0
- data/samples/compilation-steps.rb +49 -0
- data/samples/cparser_makestackoffset.rb +55 -0
- data/samples/dasm-backtrack.rb +38 -0
- data/samples/dasmnavig.rb +318 -0
- data/samples/dbg-apihook.rb +228 -0
- data/samples/dbghelp.rb +143 -0
- data/samples/disassemble-gui.rb +102 -0
- data/samples/disassemble.rb +133 -0
- data/samples/dump_upx.rb +95 -0
- data/samples/dynamic_ruby.rb +1929 -0
- data/samples/elf_list_needed.rb +46 -0
- data/samples/elf_listexports.rb +33 -0
- data/samples/elfencode.rb +25 -0
- data/samples/exeencode.rb +128 -0
- data/samples/factorize-headers-elfimports.rb +77 -0
- data/samples/factorize-headers-peimports.rb +109 -0
- data/samples/factorize-headers.rb +43 -0
- data/samples/gdbclient.rb +583 -0
- data/samples/generate_libsigs.rb +102 -0
- data/samples/hotfix_gtk_dbg.rb +59 -0
- data/samples/install_win_env.rb +78 -0
- data/samples/lindebug.rb +924 -0
- data/samples/linux_injectsyscall.rb +95 -0
- data/samples/machoencode.rb +31 -0
- data/samples/metasm-shell.rb +91 -0
- data/samples/pe-hook.rb +69 -0
- data/samples/pe-ia32-cpuid.rb +203 -0
- data/samples/pe-mips.rb +35 -0
- data/samples/pe-shutdown.rb +78 -0
- data/samples/pe-testrelocs.rb +51 -0
- data/samples/pe-testrsrc.rb +24 -0
- data/samples/pe_listexports.rb +31 -0
- data/samples/peencode.rb +19 -0
- data/samples/peldr.rb +494 -0
- data/samples/preprocess-flatten.rb +19 -0
- data/samples/r0trace.rb +308 -0
- data/samples/rubstop.rb +399 -0
- data/samples/scan_pt_gnu_stack.rb +54 -0
- data/samples/scanpeexports.rb +62 -0
- data/samples/shellcode-c.rb +40 -0
- data/samples/shellcode-dynlink.rb +146 -0
- data/samples/source.asm +34 -0
- data/samples/struct_offset.rb +47 -0
- data/samples/testpe.rb +32 -0
- data/samples/testraw.rb +45 -0
- data/samples/win32genloader.rb +132 -0
- data/samples/win32hooker-advanced.rb +169 -0
- data/samples/win32hooker.rb +96 -0
- data/samples/win32livedasm.rb +33 -0
- data/samples/win32remotescan.rb +133 -0
- data/samples/wintrace.rb +92 -0
- data/tests/all.rb +8 -0
- data/tests/dasm.rb +39 -0
- data/tests/dynldr.rb +35 -0
- data/tests/encodeddata.rb +132 -0
- data/tests/ia32.rb +82 -0
- data/tests/mips.rb +116 -0
- data/tests/parse_c.rb +239 -0
- data/tests/preprocessor.rb +269 -0
- data/tests/x86_64.rb +62 -0
- metadata +255 -0
@@ -0,0 +1,3004 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
require 'metasm/dynldr'
|
7
|
+
|
8
|
+
module Metasm
|
9
|
+
module Gui
|
10
|
+
class Win32Gui < DynLdr
|
11
|
+
new_api_c <<EOS
|
12
|
+
#line #{__LINE__}
|
13
|
+
typedef char CHAR;
|
14
|
+
typedef unsigned char BYTE;
|
15
|
+
typedef unsigned short WORD;
|
16
|
+
typedef unsigned int UINT;
|
17
|
+
typedef long LONG;
|
18
|
+
typedef unsigned long ULONG, DWORD;
|
19
|
+
typedef int BOOL;
|
20
|
+
|
21
|
+
typedef intptr_t INT_PTR, LONG_PTR;
|
22
|
+
typedef uintptr_t UINT_PTR, ULONG_PTR, DWORD_PTR;
|
23
|
+
typedef LONG_PTR LPARAM;
|
24
|
+
typedef UINT_PTR WPARAM;
|
25
|
+
typedef LONG_PTR LRESULT;
|
26
|
+
typedef const CHAR *LPSTR, *LPCSTR;
|
27
|
+
typedef void VOID, *PVOID, *LPVOID;
|
28
|
+
|
29
|
+
typedef WORD ATOM;
|
30
|
+
typedef void *HANDLE;
|
31
|
+
typedef void *HBITMAP;
|
32
|
+
typedef void *HBRUSH;
|
33
|
+
typedef void *HCURSOR;
|
34
|
+
typedef void *HDC;
|
35
|
+
typedef void *HICON;
|
36
|
+
typedef void *HINSTANCE;
|
37
|
+
typedef void *HMENU;
|
38
|
+
typedef void *HMODULE;
|
39
|
+
typedef void *HPEN;
|
40
|
+
typedef void *HWND;
|
41
|
+
|
42
|
+
#define DECLSPEC_IMPORT __declspec(dllimport)
|
43
|
+
#define WINUSERAPI DECLSPEC_IMPORT
|
44
|
+
#define WINAPI __stdcall
|
45
|
+
#define CALLBACK __stdcall
|
46
|
+
#define CONST const
|
47
|
+
#define __in __attribute__((in))
|
48
|
+
#define __out __attribute__((out))
|
49
|
+
#define __opt __attribute__((opt))
|
50
|
+
#define __inout __in __out
|
51
|
+
#define __in_opt __in __opt
|
52
|
+
#define __out_opt __out __opt
|
53
|
+
#define __in_ecount(c) __in
|
54
|
+
#define __out_ecount(c) __out
|
55
|
+
#define __inout_ecount(c) __inout
|
56
|
+
|
57
|
+
#define CW_USEDEFAULT ((int)0x80000000)
|
58
|
+
|
59
|
+
#define WS_OVERLAPPED 0x00000000L
|
60
|
+
#define WS_POPUP 0x80000000L
|
61
|
+
#define WS_CHILD 0x40000000L
|
62
|
+
#define WS_MINIMIZE 0x20000000L
|
63
|
+
#define WS_VISIBLE 0x10000000L
|
64
|
+
#define WS_DISABLED 0x08000000L
|
65
|
+
#define WS_CLIPSIBLINGS 0x04000000L
|
66
|
+
#define WS_CLIPCHILDREN 0x02000000L
|
67
|
+
#define WS_MAXIMIZE 0x01000000L
|
68
|
+
#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
|
69
|
+
#define WS_BORDER 0x00800000L
|
70
|
+
#define WS_DLGFRAME 0x00400000L
|
71
|
+
#define WS_VSCROLL 0x00200000L
|
72
|
+
#define WS_HSCROLL 0x00100000L
|
73
|
+
#define WS_SYSMENU 0x00080000L
|
74
|
+
#define WS_THICKFRAME 0x00040000L
|
75
|
+
#define WS_GROUP 0x00020000L
|
76
|
+
#define WS_TABSTOP 0x00010000L
|
77
|
+
#define WS_MINIMIZEBOX 0x00020000L
|
78
|
+
#define WS_MAXIMIZEBOX 0x00010000L
|
79
|
+
#define WS_TILED WS_OVERLAPPED
|
80
|
+
#define WS_ICONIC WS_MINIMIZE
|
81
|
+
#define WS_SIZEBOX WS_THICKFRAME
|
82
|
+
#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
|
83
|
+
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
|
84
|
+
#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
|
85
|
+
#define WS_CHILDWINDOW (WS_CHILD)
|
86
|
+
|
87
|
+
#define WS_EX_DLGMODALFRAME 0x00000001L
|
88
|
+
#define WS_EX_NOPARENTNOTIFY 0x00000004L
|
89
|
+
#define WS_EX_TOPMOST 0x00000008L
|
90
|
+
#define WS_EX_ACCEPTFILES 0x00000010L
|
91
|
+
#define WS_EX_TRANSPARENT 0x00000020L
|
92
|
+
#define WS_EX_MDICHILD 0x00000040L
|
93
|
+
#define WS_EX_TOOLWINDOW 0x00000080L
|
94
|
+
#define WS_EX_WINDOWEDGE 0x00000100L
|
95
|
+
#define WS_EX_CLIENTEDGE 0x00000200L
|
96
|
+
#define WS_EX_CONTEXTHELP 0x00000400L
|
97
|
+
#define WS_EX_RIGHT 0x00001000L
|
98
|
+
#define WS_EX_LEFT 0x00000000L
|
99
|
+
#define WS_EX_RTLREADING 0x00002000L
|
100
|
+
#define WS_EX_LTRREADING 0x00000000L
|
101
|
+
#define WS_EX_LEFTSCROLLBAR 0x00004000L
|
102
|
+
#define WS_EX_RIGHTSCROLLBAR 0x00000000L
|
103
|
+
#define WS_EX_CONTROLPARENT 0x00010000L
|
104
|
+
#define WS_EX_STATICEDGE 0x00020000L
|
105
|
+
#define WS_EX_APPWINDOW 0x00040000L
|
106
|
+
#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
|
107
|
+
#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
|
108
|
+
#define WS_EX_LAYERED 0x00080000L
|
109
|
+
#define WS_EX_NOINHERITEDLAYOUT 0x00100000L
|
110
|
+
#define WS_EX_LAYOUTRTL 0x00400000L
|
111
|
+
#define WS_EX_COMPOSITED 0x02000000L
|
112
|
+
#define WS_EX_NOACTIVATE 0x08000000L
|
113
|
+
|
114
|
+
#define WM_NULL 0x0000
|
115
|
+
#define WM_CREATE 0x0001
|
116
|
+
#define WM_DESTROY 0x0002
|
117
|
+
#define WM_MOVE 0x0003
|
118
|
+
#define WM_SIZE 0x0005
|
119
|
+
|
120
|
+
#define WM_ACTIVATE 0x0006
|
121
|
+
#define WA_INACTIVE 0
|
122
|
+
#define WA_ACTIVE 1
|
123
|
+
#define WA_CLICKACTIVE 2
|
124
|
+
|
125
|
+
#define WM_SETFOCUS 0x0007
|
126
|
+
#define WM_KILLFOCUS 0x0008
|
127
|
+
#define WM_ENABLE 0x000A
|
128
|
+
#define WM_SETREDRAW 0x000B
|
129
|
+
#define WM_SETTEXT 0x000C
|
130
|
+
#define WM_GETTEXT 0x000D
|
131
|
+
#define WM_GETTEXTLENGTH 0x000E
|
132
|
+
#define WM_PAINT 0x000F
|
133
|
+
#define WM_CLOSE 0x0010
|
134
|
+
#define WM_QUERYENDSESSION 0x0011
|
135
|
+
#define WM_QUERYOPEN 0x0013
|
136
|
+
#define WM_ENDSESSION 0x0016
|
137
|
+
#define WM_QUIT 0x0012
|
138
|
+
#define WM_ERASEBKGND 0x0014
|
139
|
+
#define WM_SYSCOLORCHANGE 0x0015
|
140
|
+
#define WM_SHOWWINDOW 0x0018
|
141
|
+
#define WM_WININICHANGE 0x001A
|
142
|
+
#define WM_SETTINGCHANGE WM_WININICHANGE
|
143
|
+
#define WM_DEVMODECHANGE 0x001B
|
144
|
+
#define WM_ACTIVATEAPP 0x001C
|
145
|
+
#define WM_FONTCHANGE 0x001D
|
146
|
+
#define WM_TIMECHANGE 0x001E
|
147
|
+
#define WM_CANCELMODE 0x001F
|
148
|
+
#define WM_SETCURSOR 0x0020
|
149
|
+
#define WM_MOUSEACTIVATE 0x0021
|
150
|
+
#define WM_CHILDACTIVATE 0x0022
|
151
|
+
#define WM_QUEUESYNC 0x0023
|
152
|
+
#define WM_GETMINMAXINFO 0x0024
|
153
|
+
typedef struct tagPOINT {
|
154
|
+
LONG x;
|
155
|
+
LONG y;
|
156
|
+
} POINT, *PPOINT, *LPPOINT;
|
157
|
+
|
158
|
+
#define WM_PAINTICON 0x0026
|
159
|
+
#define WM_ICONERASEBKGND 0x0027
|
160
|
+
#define WM_NEXTDLGCTL 0x0028
|
161
|
+
#define WM_SPOOLERSTATUS 0x002A
|
162
|
+
#define WM_DRAWITEM 0x002B
|
163
|
+
#define WM_MEASUREITEM 0x002C
|
164
|
+
#define WM_DELETEITEM 0x002D
|
165
|
+
#define WM_VKEYTOITEM 0x002E
|
166
|
+
#define WM_CHARTOITEM 0x002F
|
167
|
+
#define WM_SETFONT 0x0030
|
168
|
+
#define WM_GETFONT 0x0031
|
169
|
+
#define WM_SETHOTKEY 0x0032
|
170
|
+
#define WM_GETHOTKEY 0x0033
|
171
|
+
#define WM_QUERYDRAGICON 0x0037
|
172
|
+
#define WM_COMPAREITEM 0x0039
|
173
|
+
#define WM_GETOBJECT 0x003D
|
174
|
+
#define WM_COMPACTING 0x0041
|
175
|
+
#define WM_COMMNOTIFY 0x0044
|
176
|
+
#define WM_WINDOWPOSCHANGING 0x0046
|
177
|
+
#define WM_WINDOWPOSCHANGED 0x0047
|
178
|
+
#define WM_POWER 0x0048
|
179
|
+
#define PWR_OK 1
|
180
|
+
#define PWR_FAIL (-1)
|
181
|
+
#define PWR_SUSPENDREQUEST 1
|
182
|
+
#define PWR_SUSPENDRESUME 2
|
183
|
+
#define PWR_CRITICALRESUME 3
|
184
|
+
#define WM_COPYDATA 0x004A
|
185
|
+
#define WM_CANCELJOURNAL 0x004B
|
186
|
+
#define WM_NOTIFY 0x004E
|
187
|
+
#define WM_INPUTLANGCHANGEREQUEST 0x0050
|
188
|
+
#define WM_INPUTLANGCHANGE 0x0051
|
189
|
+
#define WM_TCARD 0x0052
|
190
|
+
#define WM_HELP 0x0053
|
191
|
+
#define WM_USERCHANGED 0x0054
|
192
|
+
#define WM_NOTIFYFORMAT 0x0055
|
193
|
+
#define NFR_ANSI 1
|
194
|
+
#define NFR_UNICODE 2
|
195
|
+
#define NF_QUERY 3
|
196
|
+
#define NF_REQUERY 4
|
197
|
+
#define WM_CONTEXTMENU 0x007B
|
198
|
+
#define WM_STYLECHANGING 0x007C
|
199
|
+
#define WM_STYLECHANGED 0x007D
|
200
|
+
#define WM_DISPLAYCHANGE 0x007E
|
201
|
+
#define WM_GETICON 0x007F
|
202
|
+
#define WM_SETICON 0x0080
|
203
|
+
#define WM_NCCREATE 0x0081
|
204
|
+
#define WM_NCDESTROY 0x0082
|
205
|
+
#define WM_NCCALCSIZE 0x0083
|
206
|
+
#define WM_NCHITTEST 0x0084
|
207
|
+
#define WM_NCPAINT 0x0085
|
208
|
+
#define WM_NCACTIVATE 0x0086
|
209
|
+
#define WM_GETDLGCODE 0x0087
|
210
|
+
#define WM_SYNCPAINT 0x0088
|
211
|
+
#define WM_NCMOUSEMOVE 0x00A0
|
212
|
+
#define WM_NCLBUTTONDOWN 0x00A1
|
213
|
+
#define WM_NCLBUTTONUP 0x00A2
|
214
|
+
#define WM_NCLBUTTONDBLCLK 0x00A3
|
215
|
+
#define WM_NCRBUTTONDOWN 0x00A4
|
216
|
+
#define WM_NCRBUTTONUP 0x00A5
|
217
|
+
#define WM_NCRBUTTONDBLCLK 0x00A6
|
218
|
+
#define WM_NCMBUTTONDOWN 0x00A7
|
219
|
+
#define WM_NCMBUTTONUP 0x00A8
|
220
|
+
#define WM_NCMBUTTONDBLCLK 0x00A9
|
221
|
+
#define WM_NCXBUTTONDOWN 0x00AB
|
222
|
+
#define WM_NCXBUTTONUP 0x00AC
|
223
|
+
#define WM_NCXBUTTONDBLCLK 0x00AD
|
224
|
+
#define WM_INPUT 0x00FF
|
225
|
+
#define WM_KEYFIRST 0x0100
|
226
|
+
#define WM_KEYDOWN 0x0100
|
227
|
+
#define WM_KEYUP 0x0101
|
228
|
+
#define WM_CHAR 0x0102
|
229
|
+
#define WM_DEADCHAR 0x0103
|
230
|
+
#define WM_SYSKEYDOWN 0x0104
|
231
|
+
#define WM_SYSKEYUP 0x0105
|
232
|
+
#define WM_SYSCHAR 0x0106
|
233
|
+
#define WM_SYSDEADCHAR 0x0107
|
234
|
+
#define WM_UNICHAR 0x0109
|
235
|
+
#define WM_KEYLAST 0x0109
|
236
|
+
#define UNICODE_NOCHAR 0xFFFF
|
237
|
+
#define WM_IME_STARTCOMPOSITION 0x010D
|
238
|
+
#define WM_IME_ENDCOMPOSITION 0x010E
|
239
|
+
#define WM_IME_COMPOSITION 0x010F
|
240
|
+
#define WM_IME_KEYLAST 0x010F
|
241
|
+
|
242
|
+
#define WM_INITDIALOG 0x0110
|
243
|
+
#define WM_COMMAND 0x0111
|
244
|
+
#define WM_SYSCOMMAND 0x0112
|
245
|
+
#define WM_TIMER 0x0113
|
246
|
+
#define WM_HSCROLL 0x0114
|
247
|
+
#define WM_VSCROLL 0x0115
|
248
|
+
#define WM_INITMENU 0x0116
|
249
|
+
#define WM_INITMENUPOPUP 0x0117
|
250
|
+
#define WM_MENUSELECT 0x011F
|
251
|
+
#define WM_MENUCHAR 0x0120
|
252
|
+
#define WM_ENTERIDLE 0x0121
|
253
|
+
#define WM_MENURBUTTONUP 0x0122
|
254
|
+
#define WM_MENUDRAG 0x0123
|
255
|
+
#define WM_MENUGETOBJECT 0x0124
|
256
|
+
#define WM_UNINITMENUPOPUP 0x0125
|
257
|
+
#define WM_MENUCOMMAND 0x0126
|
258
|
+
#define WM_CHANGEUISTATE 0x0127
|
259
|
+
#define WM_UPDATEUISTATE 0x0128
|
260
|
+
#define WM_QUERYUISTATE 0x0129
|
261
|
+
#define UIS_SET 1
|
262
|
+
#define UIS_CLEAR 2
|
263
|
+
#define UIS_INITIALIZE 3
|
264
|
+
#define UISF_HIDEFOCUS 0x1
|
265
|
+
#define UISF_HIDEACCEL 0x2
|
266
|
+
#define WM_CTLCOLORMSGBOX 0x0132
|
267
|
+
#define WM_CTLCOLOREDIT 0x0133
|
268
|
+
#define WM_CTLCOLORLISTBOX 0x0134
|
269
|
+
#define WM_CTLCOLORBTN 0x0135
|
270
|
+
#define WM_CTLCOLORDLG 0x0136
|
271
|
+
#define WM_CTLCOLORSCROLLBAR 0x0137
|
272
|
+
#define WM_CTLCOLORSTATIC 0x0138
|
273
|
+
#define MN_GETHMENU 0x01E1
|
274
|
+
#define WM_MOUSEFIRST 0x0200
|
275
|
+
#define WM_MOUSEMOVE 0x0200
|
276
|
+
#define WM_LBUTTONDOWN 0x0201
|
277
|
+
#define WM_LBUTTONUP 0x0202
|
278
|
+
#define WM_LBUTTONDBLCLK 0x0203
|
279
|
+
#define WM_RBUTTONDOWN 0x0204
|
280
|
+
#define WM_RBUTTONUP 0x0205
|
281
|
+
#define WM_RBUTTONDBLCLK 0x0206
|
282
|
+
#define WM_MBUTTONDOWN 0x0207
|
283
|
+
#define WM_MBUTTONUP 0x0208
|
284
|
+
#define WM_MBUTTONDBLCLK 0x0209
|
285
|
+
#define WM_MOUSEWHEEL 0x020A
|
286
|
+
#define WM_XBUTTONDOWN 0x020B
|
287
|
+
#define WM_XBUTTONUP 0x020C
|
288
|
+
#define WM_XBUTTONDBLCLK 0x020D
|
289
|
+
#define WHEEL_DELTA 120
|
290
|
+
|
291
|
+
#define WHEEL_PAGESCROLL (UINT_MAX)
|
292
|
+
#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
|
293
|
+
#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
|
294
|
+
#define GET_NCHITTEST_WPARAM(wParam) ((short)LOWORD(wParam))
|
295
|
+
#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
|
296
|
+
|
297
|
+
#define XBUTTON1 0x0001
|
298
|
+
#define XBUTTON2 0x0002
|
299
|
+
|
300
|
+
#define WM_PARENTNOTIFY 0x0210
|
301
|
+
#define WM_ENTERMENULOOP 0x0211
|
302
|
+
#define WM_EXITMENULOOP 0x0212
|
303
|
+
#define WM_NEXTMENU 0x0213
|
304
|
+
#define WM_SIZING 0x0214
|
305
|
+
#define WM_CAPTURECHANGED 0x0215
|
306
|
+
#define WM_MOVING 0x0216
|
307
|
+
#define WM_DEVICECHANGE 0x0219
|
308
|
+
#define WM_MDICREATE 0x0220
|
309
|
+
#define WM_MDIDESTROY 0x0221
|
310
|
+
#define WM_MDIACTIVATE 0x0222
|
311
|
+
#define WM_MDIRESTORE 0x0223
|
312
|
+
#define WM_MDINEXT 0x0224
|
313
|
+
#define WM_MDIMAXIMIZE 0x0225
|
314
|
+
#define WM_MDITILE 0x0226
|
315
|
+
#define WM_MDICASCADE 0x0227
|
316
|
+
#define WM_MDIICONARRANGE 0x0228
|
317
|
+
#define WM_MDIGETACTIVE 0x0229
|
318
|
+
#define WM_MDISETMENU 0x0230
|
319
|
+
#define WM_ENTERSIZEMOVE 0x0231
|
320
|
+
#define WM_EXITSIZEMOVE 0x0232
|
321
|
+
#define WM_DROPFILES 0x0233
|
322
|
+
#define WM_MDIREFRESHMENU 0x0234
|
323
|
+
#define WM_IME_SETCONTEXT 0x0281
|
324
|
+
#define WM_IME_NOTIFY 0x0282
|
325
|
+
#define WM_IME_CONTROL 0x0283
|
326
|
+
#define WM_IME_COMPOSITIONFULL 0x0284
|
327
|
+
#define WM_IME_SELECT 0x0285
|
328
|
+
#define WM_IME_CHAR 0x0286
|
329
|
+
#define WM_IME_REQUEST 0x0288
|
330
|
+
#define WM_IME_KEYDOWN 0x0290
|
331
|
+
#define WM_IME_KEYUP 0x0291
|
332
|
+
#define WM_NCMOUSEHOVER 0x02A0
|
333
|
+
#define WM_MOUSEHOVER 0x02A1
|
334
|
+
#define WM_NCMOUSELEAVE 0x02A2
|
335
|
+
#define WM_MOUSELEAVE 0x02A3
|
336
|
+
#define WM_WTSSESSION_CHANGE 0x02B1
|
337
|
+
#define WM_TABLET_FIRST 0x02c0
|
338
|
+
#define WM_TABLET_LAST 0x02df
|
339
|
+
#define WM_CUT 0x0300
|
340
|
+
#define WM_COPY 0x0301
|
341
|
+
#define WM_PASTE 0x0302
|
342
|
+
#define WM_CLEAR 0x0303
|
343
|
+
#define WM_UNDO 0x0304
|
344
|
+
#define WM_RENDERFORMAT 0x0305
|
345
|
+
#define WM_RENDERALLFORMATS 0x0306
|
346
|
+
#define WM_DESTROYCLIPBOARD 0x0307
|
347
|
+
#define WM_DRAWCLIPBOARD 0x0308
|
348
|
+
#define WM_PAINTCLIPBOARD 0x0309
|
349
|
+
#define WM_VSCROLLCLIPBOARD 0x030A
|
350
|
+
#define WM_SIZECLIPBOARD 0x030B
|
351
|
+
#define WM_ASKCBFORMATNAME 0x030C
|
352
|
+
#define WM_CHANGECBCHAIN 0x030D
|
353
|
+
#define WM_HSCROLLCLIPBOARD 0x030E
|
354
|
+
#define WM_QUERYNEWPALETTE 0x030F
|
355
|
+
#define WM_PALETTEISCHANGING 0x0310
|
356
|
+
#define WM_PALETTECHANGED 0x0311
|
357
|
+
#define WM_HOTKEY 0x0312
|
358
|
+
#define WM_PRINT 0x0317
|
359
|
+
#define WM_PRINTCLIENT 0x0318
|
360
|
+
#define WM_APPCOMMAND 0x0319
|
361
|
+
#define WM_THEMECHANGED 0x031A
|
362
|
+
#define WM_HANDHELDFIRST 0x0358
|
363
|
+
#define WM_HANDHELDLAST 0x035F
|
364
|
+
#define WM_AFXFIRST 0x0360
|
365
|
+
#define WM_AFXLAST 0x037F
|
366
|
+
#define WM_PENWINFIRST 0x0380
|
367
|
+
#define WM_PENWINLAST 0x038F
|
368
|
+
#define WM_USER 0x0400
|
369
|
+
#define WM_APP 0x8000
|
370
|
+
|
371
|
+
#define WMSZ_LEFT 1
|
372
|
+
#define WMSZ_RIGHT 2
|
373
|
+
#define WMSZ_TOP 3
|
374
|
+
#define WMSZ_TOPLEFT 4
|
375
|
+
#define WMSZ_TOPRIGHT 5
|
376
|
+
#define WMSZ_BOTTOM 6
|
377
|
+
#define WMSZ_BOTTOMLEFT 7
|
378
|
+
#define WMSZ_BOTTOMRIGHT 8
|
379
|
+
|
380
|
+
#define SWP_NOSIZE 0x0001
|
381
|
+
#define SWP_NOMOVE 0x0002
|
382
|
+
#define SWP_NOZORDER 0x0004
|
383
|
+
#define SWP_NOREDRAW 0x0008
|
384
|
+
#define SWP_NOACTIVATE 0x0010
|
385
|
+
#define SWP_FRAMECHANGED 0x0020 /* The frame changed: send WM_NCCALCSIZE */
|
386
|
+
#define SWP_SHOWWINDOW 0x0040
|
387
|
+
#define SWP_HIDEWINDOW 0x0080
|
388
|
+
#define SWP_NOCOPYBITS 0x0100
|
389
|
+
#define SWP_NOOWNERZORDER 0x0200 /* Don't do owner Z ordering */
|
390
|
+
#define SWP_NOSENDCHANGING 0x0400 /* Don't send WM_WINDOWPOSCHANGING */
|
391
|
+
#define SWP_DRAWFRAME SWP_FRAMECHANGED
|
392
|
+
#define SWP_NOREPOSITION SWP_NOOWNERZORDER
|
393
|
+
#define SWP_DEFERERASE 0x2000
|
394
|
+
#define SWP_ASYNCWINDOWPOS 0x4000
|
395
|
+
|
396
|
+
#define HWND_TOP 0
|
397
|
+
#define HWND_BOTTOM 1
|
398
|
+
#define HWND_TOPMOST -1
|
399
|
+
#define HWND_NOTOPMOST -2
|
400
|
+
|
401
|
+
#define SIZE_RESTORED 0
|
402
|
+
#define SIZE_MINIMIZED 1
|
403
|
+
#define SIZE_MAXIMIZED 2
|
404
|
+
#define SIZE_MAXSHOW 3
|
405
|
+
#define SIZE_MAXHIDE 4
|
406
|
+
|
407
|
+
#define MK_LBUTTON 0x0001
|
408
|
+
#define MK_RBUTTON 0x0002
|
409
|
+
#define MK_SHIFT 0x0004
|
410
|
+
#define MK_CONTROL 0x0008
|
411
|
+
#define MK_MBUTTON 0x0010
|
412
|
+
#define MK_XBUTTON1 0x0020
|
413
|
+
#define MK_XBUTTON2 0x0040
|
414
|
+
|
415
|
+
typedef struct tagTRACKMOUSEEVENT {
|
416
|
+
DWORD cbSize;
|
417
|
+
DWORD dwFlags;
|
418
|
+
HWND hwndTrack;
|
419
|
+
DWORD dwHoverTime;
|
420
|
+
} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
|
421
|
+
|
422
|
+
WINUSERAPI
|
423
|
+
BOOL
|
424
|
+
WINAPI
|
425
|
+
TrackMouseEvent(
|
426
|
+
__inout LPTRACKMOUSEEVENT lpEventTrack);
|
427
|
+
|
428
|
+
#define FVIRTKEY TRUE /* Assumed to be == TRUE */
|
429
|
+
#define FNOINVERT 0x02
|
430
|
+
#define FSHIFT 0x04
|
431
|
+
#define FCONTROL 0x08
|
432
|
+
#define FALT 0x10
|
433
|
+
|
434
|
+
#define FALSE 0
|
435
|
+
#define TRUE 1
|
436
|
+
|
437
|
+
#define SW_HIDE 0
|
438
|
+
#define SW_SHOWNORMAL 1
|
439
|
+
#define SW_NORMAL 1
|
440
|
+
#define SW_SHOWMINIMIZED 2
|
441
|
+
#define SW_SHOWMAXIMIZED 3
|
442
|
+
#define SW_MAXIMIZE 3
|
443
|
+
#define SW_SHOWNOACTIVATE 4
|
444
|
+
#define SW_SHOW 5
|
445
|
+
#define SW_MINIMIZE 6
|
446
|
+
#define SW_SHOWMINNOACTIVE 7
|
447
|
+
#define SW_SHOWNA 8
|
448
|
+
#define SW_RESTORE 9
|
449
|
+
#define SW_SHOWDEFAULT 10
|
450
|
+
#define SW_FORCEMINIMIZE 11
|
451
|
+
#define SW_MAX 11
|
452
|
+
|
453
|
+
#define CS_VREDRAW 0x0001
|
454
|
+
#define CS_HREDRAW 0x0002
|
455
|
+
#define CS_DBLCLKS 0x0008
|
456
|
+
#define CS_OWNDC 0x0020
|
457
|
+
#define CS_CLASSDC 0x0040
|
458
|
+
#define CS_PARENTDC 0x0080
|
459
|
+
#define CS_NOCLOSE 0x0200
|
460
|
+
#define CS_SAVEBITS 0x0800
|
461
|
+
#define CS_BYTEALIGNCLIENT 0x1000
|
462
|
+
#define CS_BYTEALIGNWINDOW 0x2000
|
463
|
+
#define CS_GLOBALCLASS 0x4000
|
464
|
+
#define CS_IME 0x00010000
|
465
|
+
#define CS_DROPSHADOW 0x00020000
|
466
|
+
|
467
|
+
#define MF_INSERT 0x00000000L
|
468
|
+
#define MF_CHANGE 0x00000080L
|
469
|
+
#define MF_APPEND 0x00000100L
|
470
|
+
#define MF_DELETE 0x00000200L
|
471
|
+
#define MF_REMOVE 0x00001000L
|
472
|
+
#define MF_BYCOMMAND 0x00000000L
|
473
|
+
#define MF_BYPOSITION 0x00000400L
|
474
|
+
#define MF_SEPARATOR 0x00000800L
|
475
|
+
#define MF_ENABLED 0x00000000L
|
476
|
+
#define MF_GRAYED 0x00000001L
|
477
|
+
#define MF_DISABLED 0x00000002L
|
478
|
+
#define MF_UNCHECKED 0x00000000L
|
479
|
+
#define MF_CHECKED 0x00000008L
|
480
|
+
#define MF_USECHECKBITMAPS 0x00000200L
|
481
|
+
#define MF_STRING 0x00000000L
|
482
|
+
#define MF_BITMAP 0x00000004L
|
483
|
+
#define MF_OWNERDRAW 0x00000100L
|
484
|
+
#define MF_POPUP 0x00000010L
|
485
|
+
#define MF_MENUBARBREAK 0x00000020L
|
486
|
+
#define MF_MENUBREAK 0x00000040L
|
487
|
+
#define MF_UNHILITE 0x00000000L
|
488
|
+
#define MF_HILITE 0x00000080L
|
489
|
+
#define MF_DEFAULT 0x00001000L
|
490
|
+
#define MF_SYSMENU 0x00002000L
|
491
|
+
#define MF_HELP 0x00004000L
|
492
|
+
#define MF_RIGHTJUSTIFY 0x00004000L
|
493
|
+
#define MF_MOUSESELECT 0x00008000L
|
494
|
+
|
495
|
+
#define IDI_APPLICATION 32512
|
496
|
+
#define IDI_HAND 32513
|
497
|
+
#define IDI_QUESTION 32514
|
498
|
+
#define IDI_EXCLAMATION 32515
|
499
|
+
#define IDI_ASTERISK 32516
|
500
|
+
#define IDI_WINLOGO 32517
|
501
|
+
|
502
|
+
#define MB_OK 0x00000000L
|
503
|
+
#define MB_OKCANCEL 0x00000001L
|
504
|
+
#define MB_ABORTRETRYIGNORE 0x00000002L
|
505
|
+
#define MB_YESNOCANCEL 0x00000003L
|
506
|
+
#define MB_YESNO 0x00000004L
|
507
|
+
#define MB_RETRYCANCEL 0x00000005L
|
508
|
+
#define MB_CANCELTRYCONTINUE 0x00000006L
|
509
|
+
#define MB_ICONHAND 0x00000010L
|
510
|
+
#define MB_ICONQUESTION 0x00000020L
|
511
|
+
#define MB_ICONEXCLAMATION 0x00000030L
|
512
|
+
#define MB_ICONASTERISK 0x00000040L
|
513
|
+
#define MB_USERICON 0x00000080L
|
514
|
+
#define MB_ICONWARNING MB_ICONEXCLAMATION
|
515
|
+
#define MB_ICONERROR MB_ICONHAND
|
516
|
+
#define MB_ICONINFORMATION MB_ICONASTERISK
|
517
|
+
#define MB_ICONSTOP MB_ICONHAND
|
518
|
+
#define MB_DEFBUTTON1 0x00000000L
|
519
|
+
#define MB_DEFBUTTON2 0x00000100L
|
520
|
+
#define MB_DEFBUTTON3 0x00000200L
|
521
|
+
#define MB_DEFBUTTON4 0x00000300L
|
522
|
+
#define MB_APPLMODAL 0x00000000L
|
523
|
+
#define MB_SYSTEMMODAL 0x00001000L
|
524
|
+
#define MB_TASKMODAL 0x00002000L
|
525
|
+
#define MB_HELP 0x00004000L
|
526
|
+
#define MB_NOFOCUS 0x00008000L
|
527
|
+
#define MB_SETFOREGROUND 0x00010000L
|
528
|
+
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L
|
529
|
+
#define MB_TOPMOST 0x00040000L
|
530
|
+
#define MB_RIGHT 0x00080000L
|
531
|
+
#define MB_RTLREADING 0x00100000L
|
532
|
+
#define MB_SERVICE_NOTIFICATION 0x00200000L
|
533
|
+
#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L
|
534
|
+
|
535
|
+
#define IDOK 1
|
536
|
+
#define IDCANCEL 2
|
537
|
+
#define IDABORT 3
|
538
|
+
#define IDRETRY 4
|
539
|
+
#define IDIGNORE 5
|
540
|
+
#define IDYES 6
|
541
|
+
#define IDNO 7
|
542
|
+
#define IDCLOSE 8
|
543
|
+
#define IDHELP 9
|
544
|
+
#define IDTRYAGAIN 10
|
545
|
+
#define IDCONTINUE 11
|
546
|
+
#define IDTIMEOUT 32000
|
547
|
+
|
548
|
+
#define PM_NOREMOVE 0
|
549
|
+
#define PM_REMOVE 1
|
550
|
+
#define PM_NOYIELD 2
|
551
|
+
|
552
|
+
#define IDC_ARROW 32512
|
553
|
+
#define IDC_IBEAM 32513
|
554
|
+
#define IDC_WAIT 32514
|
555
|
+
#define IDC_CROSS 32515
|
556
|
+
#define IDC_UPARROW 32516
|
557
|
+
#define IDC_SIZE 32640
|
558
|
+
#define IDC_ICON 32641
|
559
|
+
#define IDC_SIZENWSE 32642
|
560
|
+
#define IDC_SIZENESW 32643
|
561
|
+
#define IDC_SIZEWE 32644
|
562
|
+
#define IDC_SIZENS 32645
|
563
|
+
#define IDC_SIZEALL 32646
|
564
|
+
#define IDC_NO 32648
|
565
|
+
#define IDC_HAND 32649
|
566
|
+
#define IDC_APPSTARTING 32650
|
567
|
+
#define IDC_HELP 32651
|
568
|
+
|
569
|
+
#define WHITE_BRUSH 0
|
570
|
+
#define LTGRAY_BRUSH 1
|
571
|
+
#define GRAY_BRUSH 2
|
572
|
+
#define DKGRAY_BRUSH 3
|
573
|
+
#define BLACK_BRUSH 4
|
574
|
+
#define NULL_BRUSH 5
|
575
|
+
#define HOLLOW_BRUSH NULL_BRUSH
|
576
|
+
#define WHITE_PEN 6
|
577
|
+
#define BLACK_PEN 7
|
578
|
+
#define NULL_PEN 8
|
579
|
+
#define OEM_FIXED_FONT 10
|
580
|
+
#define ANSI_FIXED_FONT 11
|
581
|
+
#define ANSI_VAR_FONT 12
|
582
|
+
#define SYSTEM_FONT 13
|
583
|
+
#define DEVICE_DEFAULT_FONT 14
|
584
|
+
#define DEFAULT_PALETTE 15
|
585
|
+
#define SYSTEM_FIXED_FONT 16
|
586
|
+
#define DEFAULT_GUI_FONT 17
|
587
|
+
#define DC_BRUSH 18
|
588
|
+
#define DC_PEN 19
|
589
|
+
|
590
|
+
#define VK_LBUTTON 0x01
|
591
|
+
#define VK_RBUTTON 0x02
|
592
|
+
#define VK_CANCEL 0x03
|
593
|
+
#define VK_MBUTTON 0x04
|
594
|
+
#define VK_XBUTTON1 0x05
|
595
|
+
#define VK_XBUTTON2 0x06
|
596
|
+
#define VK_BACK 0x08
|
597
|
+
#define VK_TAB 0x09
|
598
|
+
#define VK_CLEAR 0x0C
|
599
|
+
#define VK_RETURN 0x0D
|
600
|
+
#define VK_SHIFT 0x10
|
601
|
+
#define VK_CONTROL 0x11
|
602
|
+
#define VK_MENU 0x12
|
603
|
+
#define VK_PAUSE 0x13
|
604
|
+
#define VK_CAPITAL 0x14
|
605
|
+
#define VK_ESCAPE 0x1B
|
606
|
+
#define VK_CONVERT 0x1C
|
607
|
+
#define VK_NONCONVERT 0x1D
|
608
|
+
#define VK_ACCEPT 0x1E
|
609
|
+
#define VK_MODECHANGE 0x1F
|
610
|
+
#define VK_SPACE 0x20
|
611
|
+
#define VK_PRIOR 0x21
|
612
|
+
#define VK_NEXT 0x22
|
613
|
+
#define VK_END 0x23
|
614
|
+
#define VK_HOME 0x24
|
615
|
+
#define VK_LEFT 0x25
|
616
|
+
#define VK_UP 0x26
|
617
|
+
#define VK_RIGHT 0x27
|
618
|
+
#define VK_DOWN 0x28
|
619
|
+
#define VK_SELECT 0x29
|
620
|
+
#define VK_PRINT 0x2A
|
621
|
+
#define VK_EXECUTE 0x2B
|
622
|
+
#define VK_SNAPSHOT 0x2C
|
623
|
+
#define VK_INSERT 0x2D
|
624
|
+
#define VK_DELETE 0x2E
|
625
|
+
#define VK_HELP 0x2F
|
626
|
+
// VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
|
627
|
+
// VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
|
628
|
+
#define VK_LWIN 0x5B
|
629
|
+
#define VK_RWIN 0x5C
|
630
|
+
#define VK_APPS 0x5D
|
631
|
+
#define VK_SLEEP 0x5F
|
632
|
+
#define VK_NUMPAD0 0x60
|
633
|
+
#define VK_NUMPAD1 0x61
|
634
|
+
#define VK_NUMPAD2 0x62
|
635
|
+
#define VK_NUMPAD3 0x63
|
636
|
+
#define VK_NUMPAD4 0x64
|
637
|
+
#define VK_NUMPAD5 0x65
|
638
|
+
#define VK_NUMPAD6 0x66
|
639
|
+
#define VK_NUMPAD7 0x67
|
640
|
+
#define VK_NUMPAD8 0x68
|
641
|
+
#define VK_NUMPAD9 0x69
|
642
|
+
#define VK_MULTIPLY 0x6A
|
643
|
+
#define VK_ADD 0x6B
|
644
|
+
#define VK_SEPARATOR 0x6C
|
645
|
+
#define VK_SUBTRACT 0x6D
|
646
|
+
#define VK_DECIMAL 0x6E
|
647
|
+
#define VK_DIVIDE 0x6F
|
648
|
+
#define VK_F1 0x70
|
649
|
+
#define VK_F2 0x71
|
650
|
+
#define VK_F3 0x72
|
651
|
+
#define VK_F4 0x73
|
652
|
+
#define VK_F5 0x74
|
653
|
+
#define VK_F6 0x75
|
654
|
+
#define VK_F7 0x76
|
655
|
+
#define VK_F8 0x77
|
656
|
+
#define VK_F9 0x78
|
657
|
+
#define VK_F10 0x79
|
658
|
+
#define VK_F11 0x7A
|
659
|
+
#define VK_F12 0x7B
|
660
|
+
#define VK_F13 0x7C
|
661
|
+
#define VK_F14 0x7D
|
662
|
+
#define VK_F15 0x7E
|
663
|
+
#define VK_F16 0x7F
|
664
|
+
#define VK_F17 0x80
|
665
|
+
#define VK_F18 0x81
|
666
|
+
#define VK_F19 0x82
|
667
|
+
#define VK_F20 0x83
|
668
|
+
#define VK_F21 0x84
|
669
|
+
#define VK_F22 0x85
|
670
|
+
#define VK_F23 0x86
|
671
|
+
#define VK_F24 0x87
|
672
|
+
|
673
|
+
#define QS_KEY 0x0001
|
674
|
+
#define QS_MOUSEMOVE 0x0002
|
675
|
+
#define QS_MOUSEBUTTON 0x0004
|
676
|
+
#define QS_POSTMESSAGE 0x0008
|
677
|
+
#define QS_TIMER 0x0010
|
678
|
+
#define QS_PAINT 0x0020
|
679
|
+
#define QS_SENDMESSAGE 0x0040
|
680
|
+
#define QS_HOTKEY 0x0080
|
681
|
+
#define QS_ALLPOSTMESSAGE 0x0100
|
682
|
+
#define QS_RAWINPUT 0x0400
|
683
|
+
#define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON)
|
684
|
+
#define QS_INPUT (QS_MOUSE | QS_KEY | QS_RAWINPUT)
|
685
|
+
#define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY)
|
686
|
+
#define QS_ALLINPUT (QS_ALLEVENTS | QS_SENDMESSAGE)
|
687
|
+
|
688
|
+
#define WAIT_TIMEOUT 258L
|
689
|
+
|
690
|
+
#define CF_TEXT 1
|
691
|
+
#define CF_BITMAP 2
|
692
|
+
#define CF_METAFILEPICT 3
|
693
|
+
#define CF_SYLK 4
|
694
|
+
#define CF_DIF 5
|
695
|
+
#define CF_TIFF 6
|
696
|
+
#define CF_OEMTEXT 7
|
697
|
+
#define CF_DIB 8
|
698
|
+
#define CF_PALETTE 9
|
699
|
+
#define CF_PENDATA 10
|
700
|
+
#define CF_RIFF 11
|
701
|
+
#define CF_WAVE 12
|
702
|
+
#define CF_UNICODETEXT 13
|
703
|
+
#define CF_ENHMETAFILE 14
|
704
|
+
#define CF_HDROP 15
|
705
|
+
#define CF_LOCALE 16
|
706
|
+
#define CF_DIBV5 17
|
707
|
+
|
708
|
+
#define COLOR_SCROLLBAR 0
|
709
|
+
#define COLOR_BACKGROUND 1
|
710
|
+
#define COLOR_ACTIVECAPTION 2
|
711
|
+
#define COLOR_INACTIVECAPTION 3
|
712
|
+
#define COLOR_MENU 4
|
713
|
+
#define COLOR_WINDOW 5
|
714
|
+
#define COLOR_WINDOWFRAME 6
|
715
|
+
#define COLOR_MENUTEXT 7
|
716
|
+
#define COLOR_WINDOWTEXT 8
|
717
|
+
#define COLOR_CAPTIONTEXT 9
|
718
|
+
#define COLOR_ACTIVEBORDER 10
|
719
|
+
#define COLOR_INACTIVEBORDER 11
|
720
|
+
#define COLOR_APPWORKSPACE 12
|
721
|
+
#define COLOR_HIGHLIGHT 13
|
722
|
+
#define COLOR_HIGHLIGHTTEXT 14
|
723
|
+
#define COLOR_BTNFACE 15
|
724
|
+
#define COLOR_BTNSHADOW 16
|
725
|
+
#define COLOR_GRAYTEXT 17
|
726
|
+
#define COLOR_BTNTEXT 18
|
727
|
+
#define COLOR_INACTIVECAPTIONTEXT 19
|
728
|
+
#define COLOR_BTNHIGHLIGHT 20
|
729
|
+
#define COLOR_3DDKSHADOW 21
|
730
|
+
#define COLOR_3DLIGHT 22
|
731
|
+
#define COLOR_INFOTEXT 23
|
732
|
+
#define COLOR_INFOBK 24
|
733
|
+
#define COLOR_HOTLIGHT 26
|
734
|
+
#define COLOR_GRADIENTACTIVECAPTION 27
|
735
|
+
#define COLOR_GRADIENTINACTIVECAPTION 28
|
736
|
+
#define COLOR_MENUHILIGHT 29
|
737
|
+
#define COLOR_MENUBAR 30
|
738
|
+
#define COLOR_DESKTOP COLOR_BACKGROUND
|
739
|
+
#define COLOR_3DFACE COLOR_BTNFACE
|
740
|
+
#define COLOR_3DSHADOW COLOR_BTNSHADOW
|
741
|
+
#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT
|
742
|
+
#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT
|
743
|
+
#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT
|
744
|
+
|
745
|
+
|
746
|
+
WINUSERAPI DWORD WINAPI GetSysColor(__in int nIndex);
|
747
|
+
|
748
|
+
|
749
|
+
WINUSERAPI
|
750
|
+
int
|
751
|
+
WINAPI
|
752
|
+
GetSystemMetrics(
|
753
|
+
__in int nIndex);
|
754
|
+
|
755
|
+
typedef struct tagMSG {
|
756
|
+
HWND hwnd;
|
757
|
+
UINT message;
|
758
|
+
WPARAM wParam;
|
759
|
+
LPARAM lParam;
|
760
|
+
DWORD time;
|
761
|
+
POINT pt;
|
762
|
+
} MSG, *PMSG, *LPMSG;
|
763
|
+
|
764
|
+
WINUSERAPI
|
765
|
+
BOOL
|
766
|
+
WINAPI
|
767
|
+
GetMessageA(
|
768
|
+
__out LPMSG lpMsg,
|
769
|
+
__in_opt HWND hWnd,
|
770
|
+
__in UINT wMsgFilterMin,
|
771
|
+
__in UINT wMsgFilterMax);
|
772
|
+
WINUSERAPI
|
773
|
+
BOOL
|
774
|
+
WINAPI
|
775
|
+
PeekMessageA(
|
776
|
+
__out LPMSG lpMsg,
|
777
|
+
__in_opt HWND hWnd,
|
778
|
+
__in UINT wMsgFilterMin,
|
779
|
+
__in UINT wMsgFilterMax,
|
780
|
+
__in UINT wRemoveMsg);
|
781
|
+
WINUSERAPI
|
782
|
+
BOOL
|
783
|
+
WINAPI
|
784
|
+
TranslateMessage(
|
785
|
+
__in CONST MSG *lpMsg);
|
786
|
+
WINUSERAPI
|
787
|
+
LRESULT
|
788
|
+
WINAPI
|
789
|
+
DispatchMessageA(
|
790
|
+
__in CONST MSG *lpMsg);
|
791
|
+
#define MOD_ALT 0x0001
|
792
|
+
#define MOD_CONTROL 0x0002
|
793
|
+
#define MOD_SHIFT 0x0004
|
794
|
+
#define MOD_WIN 0x0008
|
795
|
+
WINUSERAPI
|
796
|
+
LRESULT
|
797
|
+
WINAPI
|
798
|
+
SendMessageA(
|
799
|
+
__in HWND hWnd,
|
800
|
+
__in UINT Msg,
|
801
|
+
__in WPARAM wParam,
|
802
|
+
__in LPARAM lParam);
|
803
|
+
WINUSERAPI
|
804
|
+
BOOL
|
805
|
+
WINAPI
|
806
|
+
PostMessageA(
|
807
|
+
__in_opt HWND hWnd,
|
808
|
+
__in UINT Msg,
|
809
|
+
__in WPARAM wParam,
|
810
|
+
__in LPARAM lParam);
|
811
|
+
WINUSERAPI
|
812
|
+
LRESULT
|
813
|
+
WINAPI
|
814
|
+
DefWindowProcA(
|
815
|
+
__in HWND hWnd,
|
816
|
+
__in UINT Msg,
|
817
|
+
__in WPARAM wParam,
|
818
|
+
__in LPARAM lParam);
|
819
|
+
WINUSERAPI
|
820
|
+
VOID
|
821
|
+
WINAPI
|
822
|
+
PostQuitMessage(
|
823
|
+
__in int nExitCode);
|
824
|
+
WINUSERAPI
|
825
|
+
DWORD
|
826
|
+
WINAPI
|
827
|
+
MsgWaitForMultipleObjects(
|
828
|
+
__in DWORD nCount,
|
829
|
+
__in_opt CONST HANDLE *pHandles,
|
830
|
+
__in BOOL fWaitAll,
|
831
|
+
__in DWORD dwMilliseconds,
|
832
|
+
__in DWORD dwWakeMask);
|
833
|
+
WINUSERAPI DWORD WINAPI GetKeyState(__in int nVirtKey);
|
834
|
+
|
835
|
+
WINUSERAPI BOOL WINAPI OpenClipboard(__in_opt HWND hWndNewOwner);
|
836
|
+
WINUSERAPI BOOL WINAPI CloseClipboard(VOID);
|
837
|
+
WINUSERAPI HANDLE WINAPI SetClipboardData(__in UINT uFormat, __in_opt HANDLE hMem);
|
838
|
+
WINUSERAPI HANDLE WINAPI GetClipboardData(__in UINT uFormat);
|
839
|
+
WINUSERAPI BOOL WINAPI EmptyClipboard(VOID);
|
840
|
+
|
841
|
+
#define GMEM_FIXED 0x0000
|
842
|
+
#define GMEM_MOVEABLE 0x0002
|
843
|
+
#define GMEM_NOCOMPACT 0x0010
|
844
|
+
#define GMEM_NODISCARD 0x0020
|
845
|
+
#define GMEM_ZEROINIT 0x0040
|
846
|
+
#define GMEM_MODIFY 0x0080
|
847
|
+
#define GMEM_DISCARDABLE 0x0100
|
848
|
+
#define GMEM_NOT_BANKED 0x1000
|
849
|
+
#define GMEM_SHARE 0x2000
|
850
|
+
#define GMEM_DDESHARE 0x2000
|
851
|
+
#define GMEM_NOTIFY 0x4000
|
852
|
+
#define GMEM_LOWER GMEM_NOT_BANKED
|
853
|
+
#define GMEM_INVALID_HANDLE 0x8000
|
854
|
+
HANDLE WINAPI GlobalAlloc(__in UINT uFlags, __in DWORD dwBytes);
|
855
|
+
DWORD WINAPI GlobalSize(__in HANDLE hMem);
|
856
|
+
LPVOID WINAPI GlobalLock(__in HANDLE hMem);
|
857
|
+
BOOL WINAPI GlobalUnlock(__in HANDLE hMem);
|
858
|
+
HANDLE WINAPI GlobalFree(HANDLE hMem);
|
859
|
+
|
860
|
+
typedef __stdcall LRESULT (*WNDPROC)(HWND, UINT, WPARAM, LPARAM);
|
861
|
+
typedef struct tagWNDCLASSEXA {
|
862
|
+
UINT cbSize;
|
863
|
+
UINT style;
|
864
|
+
WNDPROC lpfnWndProc;
|
865
|
+
int cbClsExtra;
|
866
|
+
int cbWndExtra;
|
867
|
+
HINSTANCE hInstance;
|
868
|
+
HICON hIcon;
|
869
|
+
HCURSOR hCursor;
|
870
|
+
HBRUSH hbrBackground;
|
871
|
+
LPCSTR lpszMenuName;
|
872
|
+
LPCSTR lpszClassName;
|
873
|
+
HICON hIconSm;
|
874
|
+
} WNDCLASSEXA;
|
875
|
+
WINUSERAPI
|
876
|
+
ATOM
|
877
|
+
WINAPI
|
878
|
+
RegisterClassExA(
|
879
|
+
__in CONST WNDCLASSEXA *);
|
880
|
+
WINUSERAPI
|
881
|
+
HWND
|
882
|
+
WINAPI
|
883
|
+
CreateWindowExA(
|
884
|
+
__in DWORD dwExStyle,
|
885
|
+
__in_opt LPCSTR lpClassName,
|
886
|
+
__in_opt LPCSTR lpWindowName,
|
887
|
+
__in DWORD dwStyle,
|
888
|
+
__in int X,
|
889
|
+
__in int Y,
|
890
|
+
__in int nWidth,
|
891
|
+
__in int nHeight,
|
892
|
+
__in_opt HWND hWndParent,
|
893
|
+
__in_opt HMENU hMenu,
|
894
|
+
__in_opt HINSTANCE hInstance,
|
895
|
+
__in_opt LPVOID lpParam);
|
896
|
+
WINUSERAPI
|
897
|
+
BOOL
|
898
|
+
WINAPI
|
899
|
+
DestroyWindow(
|
900
|
+
__in HWND hWnd);
|
901
|
+
WINUSERAPI
|
902
|
+
BOOL
|
903
|
+
WINAPI
|
904
|
+
ShowWindow(
|
905
|
+
__in HWND hWnd,
|
906
|
+
__in int nCmdShow);
|
907
|
+
WINUSERAPI
|
908
|
+
BOOL
|
909
|
+
WINAPI
|
910
|
+
CloseWindow(
|
911
|
+
__in HWND hWnd);
|
912
|
+
WINUSERAPI
|
913
|
+
BOOL
|
914
|
+
WINAPI
|
915
|
+
MoveWindow(
|
916
|
+
__in HWND hWnd,
|
917
|
+
__in int X,
|
918
|
+
__in int Y,
|
919
|
+
__in int nWidth,
|
920
|
+
__in int nHeight,
|
921
|
+
__in BOOL bRepaint);
|
922
|
+
WINUSERAPI
|
923
|
+
BOOL
|
924
|
+
WINAPI
|
925
|
+
SetWindowPos(
|
926
|
+
__in HWND hWnd,
|
927
|
+
__in_opt HWND hWndInsertAfter,
|
928
|
+
__in int X,
|
929
|
+
__in int Y,
|
930
|
+
__in int cx,
|
931
|
+
__in int cy,
|
932
|
+
__in UINT uFlags);
|
933
|
+
#define SRCCOPY (DWORD)0x00CC0020 /* dest = source */
|
934
|
+
#define SRCPAINT (DWORD)0x00EE0086 /* dest = source OR dest */
|
935
|
+
#define SRCAND (DWORD)0x008800C6 /* dest = source AND dest */
|
936
|
+
#define SRCINVERT (DWORD)0x00660046 /* dest = source XOR dest */
|
937
|
+
#define SRCERASE (DWORD)0x00440328 /* dest = source AND (NOT dest ) */
|
938
|
+
#define NOTSRCCOPY (DWORD)0x00330008 /* dest = (NOT source) */
|
939
|
+
#define NOTSRCERASE (DWORD)0x001100A6 /* dest = (NOT src) AND (NOT dest) */
|
940
|
+
#define MERGECOPY (DWORD)0x00C000CA /* dest = (source AND pattern) */
|
941
|
+
#define MERGEPAINT (DWORD)0x00BB0226 /* dest = (NOT source) OR dest */
|
942
|
+
#define PATCOPY (DWORD)0x00F00021 /* dest = pattern */
|
943
|
+
#define PATPAINT (DWORD)0x00FB0A09 /* dest = DPSnoo */
|
944
|
+
#define PATINVERT (DWORD)0x005A0049 /* dest = pattern XOR dest */
|
945
|
+
#define DSTINVERT (DWORD)0x00550009 /* dest = (NOT dest) */
|
946
|
+
#define BLACKNESS (DWORD)0x00000042 /* dest = BLACK */
|
947
|
+
#define WHITENESS (DWORD)0x00FF0062 /* dest = WHITE */
|
948
|
+
#define NOMIRRORBITMAP (DWORD)0x80000000 /* Do not Mirror the bitmap in this call */
|
949
|
+
#define CAPTUREBLT (DWORD)0x40000000 /* Include layered windows */
|
950
|
+
BOOL WINAPI BitBlt(__in HDC hdcDst, __in int x, __in int y, __in int cx, __in int cy, __in_opt HDC hdcSrc, __in int x1, __in int y1, __in DWORD rop);
|
951
|
+
HBITMAP WINAPI CreateCompatibleBitmap(__in HDC hdc, __in int cx, __in int cy);
|
952
|
+
HDC WINAPI CreateCompatibleDC(__in_opt HDC hdc);
|
953
|
+
BOOL WINAPI DeleteDC(__in HDC hdc);
|
954
|
+
HDC WINAPI GetDC(__in_opt HWND hWnd);
|
955
|
+
int WINAPI ReleaseDC(__in_opt HWND hWnd, __in HDC hDC);
|
956
|
+
BOOL
|
957
|
+
WINAPI
|
958
|
+
GetTextExtentPoint32A(
|
959
|
+
__in HDC hdc,
|
960
|
+
__in_ecount(c) LPCSTR lpString,
|
961
|
+
__in int c,
|
962
|
+
__out LPPOINT lpsz);
|
963
|
+
WINUSERAPI
|
964
|
+
BOOL
|
965
|
+
WINAPI
|
966
|
+
SetMenu(
|
967
|
+
__in HWND hWnd,
|
968
|
+
__in_opt HMENU hMenu);
|
969
|
+
WINUSERAPI
|
970
|
+
HMENU
|
971
|
+
WINAPI
|
972
|
+
CreateMenu(VOID);
|
973
|
+
WINUSERAPI
|
974
|
+
HMENU
|
975
|
+
WINAPI
|
976
|
+
CreatePopupMenu(VOID);
|
977
|
+
WINUSERAPI
|
978
|
+
BOOL
|
979
|
+
WINAPI
|
980
|
+
DestroyMenu(
|
981
|
+
__in HMENU hMenu);
|
982
|
+
WINUSERAPI
|
983
|
+
DWORD
|
984
|
+
WINAPI
|
985
|
+
CheckMenuItem(
|
986
|
+
__in HMENU hMenu,
|
987
|
+
__in UINT uIDCheckItem,
|
988
|
+
__in UINT uCheck);
|
989
|
+
WINUSERAPI
|
990
|
+
BOOL
|
991
|
+
WINAPI
|
992
|
+
AppendMenuA(
|
993
|
+
__in HMENU hMenu,
|
994
|
+
__in UINT uFlags,
|
995
|
+
__in UINT_PTR uIDNewItem,
|
996
|
+
__in_opt LPCSTR lpNewItem);
|
997
|
+
|
998
|
+
#define TRANSPARENT 1
|
999
|
+
#define OPAQUE 2
|
1000
|
+
int WINAPI SetBkMode(__in HDC hdc, __in int mode);
|
1001
|
+
|
1002
|
+
typedef struct tagRECT {
|
1003
|
+
LONG left;
|
1004
|
+
LONG top;
|
1005
|
+
LONG right;
|
1006
|
+
LONG bottom;
|
1007
|
+
} RECT, *LPRECT;
|
1008
|
+
|
1009
|
+
WINUSERAPI
|
1010
|
+
int
|
1011
|
+
WINAPI
|
1012
|
+
DrawTextA(
|
1013
|
+
__in HDC hdc,
|
1014
|
+
__inout_ecount(cchText) LPCSTR lpchText,
|
1015
|
+
__in int cchText,
|
1016
|
+
__inout LPRECT lprc,
|
1017
|
+
__in UINT format);
|
1018
|
+
|
1019
|
+
typedef struct tagPAINTSTRUCT {
|
1020
|
+
HDC hdc;
|
1021
|
+
BOOL fErase;
|
1022
|
+
RECT rcPaint;
|
1023
|
+
BOOL fRestore;
|
1024
|
+
BOOL fIncUpdate;
|
1025
|
+
BYTE rgbReserved[32];
|
1026
|
+
} PAINTSTRUCT, *LPPAINTSTRUCT;
|
1027
|
+
WINUSERAPI
|
1028
|
+
HDC
|
1029
|
+
WINAPI
|
1030
|
+
BeginPaint(
|
1031
|
+
__in HWND hWnd,
|
1032
|
+
__out LPPAINTSTRUCT lpPaint);
|
1033
|
+
WINUSERAPI
|
1034
|
+
BOOL
|
1035
|
+
WINAPI
|
1036
|
+
EndPaint(
|
1037
|
+
__in HWND hWnd,
|
1038
|
+
__in CONST PAINTSTRUCT *lpPaint);
|
1039
|
+
WINUSERAPI
|
1040
|
+
BOOL
|
1041
|
+
WINAPI
|
1042
|
+
InvalidateRect(
|
1043
|
+
__in_opt HWND hWnd,
|
1044
|
+
__in_opt CONST RECT *lpRect,
|
1045
|
+
__in BOOL bErase);
|
1046
|
+
WINUSERAPI
|
1047
|
+
BOOL
|
1048
|
+
WINAPI
|
1049
|
+
SetWindowTextA(
|
1050
|
+
__in HWND hWnd,
|
1051
|
+
__in_opt LPCSTR lpString);
|
1052
|
+
WINUSERAPI
|
1053
|
+
int
|
1054
|
+
WINAPI
|
1055
|
+
GetWindowTextA(
|
1056
|
+
__in HWND hWnd,
|
1057
|
+
__out_ecount(nMaxCount) LPSTR lpString,
|
1058
|
+
__in int nMaxCount);
|
1059
|
+
WINUSERAPI
|
1060
|
+
int
|
1061
|
+
WINAPI
|
1062
|
+
MessageBoxA(
|
1063
|
+
__in_opt HWND hWnd,
|
1064
|
+
__in_opt LPCSTR lpText,
|
1065
|
+
__in_opt LPCSTR lpCaption,
|
1066
|
+
__in UINT uType);
|
1067
|
+
|
1068
|
+
WINUSERAPI
|
1069
|
+
HICON
|
1070
|
+
WINAPI
|
1071
|
+
LoadIconA(
|
1072
|
+
__in_opt HINSTANCE hInstance,
|
1073
|
+
__in LPCSTR lpIconName);
|
1074
|
+
WINUSERAPI
|
1075
|
+
HCURSOR
|
1076
|
+
WINAPI
|
1077
|
+
LoadCursorA(
|
1078
|
+
__in_opt HINSTANCE hInstance,
|
1079
|
+
__in LPCSTR lpCursorName);
|
1080
|
+
WINAPI PVOID GetStockObject(__in int i);
|
1081
|
+
WINUSERAPI
|
1082
|
+
BOOL
|
1083
|
+
WINAPI
|
1084
|
+
UpdateWindow(
|
1085
|
+
__in HWND hWnd);
|
1086
|
+
WINUSERAPI
|
1087
|
+
BOOL
|
1088
|
+
WINAPI
|
1089
|
+
GetClientRect(
|
1090
|
+
__in HWND hWnd,
|
1091
|
+
__out LPRECT lpRect);
|
1092
|
+
WINUSERAPI
|
1093
|
+
BOOL
|
1094
|
+
WINAPI
|
1095
|
+
GetWindowRect(
|
1096
|
+
__in HWND hWnd,
|
1097
|
+
__out LPRECT lpRect);
|
1098
|
+
WINUSERAPI
|
1099
|
+
BOOL
|
1100
|
+
WINAPI
|
1101
|
+
AdjustWindowRect(
|
1102
|
+
__inout LPRECT lpRect,
|
1103
|
+
__in DWORD dwStyle,
|
1104
|
+
__in BOOL bMenu);
|
1105
|
+
WINUSERAPI
|
1106
|
+
BOOL
|
1107
|
+
WINAPI
|
1108
|
+
AdjustWindowRectEx(
|
1109
|
+
__inout LPRECT lpRect,
|
1110
|
+
__in DWORD dwStyle,
|
1111
|
+
__in BOOL bMenu,
|
1112
|
+
__in DWORD dwExStyle);
|
1113
|
+
#define PS_SOLID 0
|
1114
|
+
#define PS_DASH 1 /* ------- */
|
1115
|
+
#define PS_DOT 2 /* ....... */
|
1116
|
+
#define PS_DASHDOT 3 /* _._._._ */
|
1117
|
+
#define PS_DASHDOTDOT 4 /* _.._.._ */
|
1118
|
+
#define PS_NULL 5
|
1119
|
+
#define PS_INSIDEFRAME 6
|
1120
|
+
#define PS_USERSTYLE 7
|
1121
|
+
#define PS_ALTERNATE 8
|
1122
|
+
DWORD WINAPI SetTextColor(__in HDC hdc, __in DWORD color);
|
1123
|
+
BOOL WINAPI TextOutA( __in HDC hdc, __in int x, __in int y, __in_ecount(c) LPCSTR lpString, __in int c);
|
1124
|
+
BOOL WINAPI MoveToEx( __in HDC hdc, __in int x, __in int y, __out_opt LPPOINT lppt);
|
1125
|
+
BOOL WINAPI LineTo( __in HDC hdc, __in int x, __in int y);
|
1126
|
+
BOOL WINAPI Rectangle(__in HDC hdc, __in int left, __in int top, __in int right, __in int bottom);
|
1127
|
+
HANDLE WINAPI SelectObject(__in HDC hdc, __in HANDLE h);
|
1128
|
+
BOOL WINAPI DeleteObject(__in HANDLE ho);
|
1129
|
+
DWORD WINAPI SetBkColor(__in HDC hdc, __in DWORD color);
|
1130
|
+
HANDLE WINAPI CreateSolidBrush(__in DWORD color);
|
1131
|
+
//DWORD WINAPI SetDCBrushColor(__in HDC hdc, __in DWORD color);
|
1132
|
+
HANDLE WINAPI CreatePen(__in int style, __in int width, __in DWORD color);
|
1133
|
+
//DWORD WINAPI SetDCPenColor(__in HDC hdc, __in DWORD color);
|
1134
|
+
int WINAPI FillRect(__in HDC hDC, __in CONST RECT *lprc, __in HBRUSH hbr);
|
1135
|
+
|
1136
|
+
WINUSERAPI HWND WINAPI GetCapture(VOID);
|
1137
|
+
WINUSERAPI HWND WINAPI SetCapture(__in HWND hWnd);
|
1138
|
+
WINUSERAPI BOOL WINAPI ReleaseCapture(VOID);
|
1139
|
+
|
1140
|
+
#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
|
1141
|
+
#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
|
1142
|
+
#define FORMAT_MESSAGE_FROM_STRING 0x00000400
|
1143
|
+
#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
|
1144
|
+
#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
|
1145
|
+
#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
|
1146
|
+
#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
|
1147
|
+
|
1148
|
+
DWORD
|
1149
|
+
WINAPI
|
1150
|
+
GetLastError(VOID);
|
1151
|
+
VOID
|
1152
|
+
WINAPI
|
1153
|
+
SetLastError(
|
1154
|
+
__in DWORD dwErrCode
|
1155
|
+
);
|
1156
|
+
DWORD
|
1157
|
+
WINAPI
|
1158
|
+
FormatMessageA(
|
1159
|
+
DWORD dwFlags,
|
1160
|
+
LPVOID lpSource,
|
1161
|
+
DWORD dwMessageId,
|
1162
|
+
DWORD dwLanguageId,
|
1163
|
+
LPSTR lpBuffer,
|
1164
|
+
DWORD nSize,
|
1165
|
+
void *Arguments
|
1166
|
+
);
|
1167
|
+
|
1168
|
+
#define OFN_READONLY 0x00000001
|
1169
|
+
#define OFN_OVERWRITEPROMPT 0x00000002
|
1170
|
+
#define OFN_HIDEREADONLY 0x00000004
|
1171
|
+
#define OFN_NOCHANGEDIR 0x00000008
|
1172
|
+
#define OFN_SHOWHELP 0x00000010
|
1173
|
+
#define OFN_ENABLEHOOK 0x00000020
|
1174
|
+
#define OFN_ENABLETEMPLATE 0x00000040
|
1175
|
+
#define OFN_ENABLETEMPLATEHANDLE 0x00000080
|
1176
|
+
#define OFN_NOVALIDATE 0x00000100
|
1177
|
+
#define OFN_ALLOWMULTISELECT 0x00000200
|
1178
|
+
#define OFN_EXTENSIONDIFFERENT 0x00000400
|
1179
|
+
#define OFN_PATHMUSTEXIST 0x00000800
|
1180
|
+
#define OFN_FILEMUSTEXIST 0x00001000
|
1181
|
+
#define OFN_CREATEPROMPT 0x00002000
|
1182
|
+
#define OFN_SHAREAWARE 0x00004000
|
1183
|
+
#define OFN_NOREADONLYRETURN 0x00008000
|
1184
|
+
#define OFN_NOTESTFILECREATE 0x00010000
|
1185
|
+
#define OFN_NONETWORKBUTTON 0x00020000
|
1186
|
+
#define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules
|
1187
|
+
#define OFN_EXPLORER 0x00080000 // new look commdlg
|
1188
|
+
#define OFN_NODEREFERENCELINKS 0x00100000
|
1189
|
+
#define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules
|
1190
|
+
#define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback
|
1191
|
+
#define OFN_ENABLESIZING 0x00800000
|
1192
|
+
#define OFN_DONTADDTORECENT 0x02000000
|
1193
|
+
#define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files
|
1194
|
+
typedef struct tagOFNA {
|
1195
|
+
DWORD lStructSize;
|
1196
|
+
HWND hwndOwner;
|
1197
|
+
HINSTANCE hInstance;
|
1198
|
+
LPCSTR lpstrFilter;
|
1199
|
+
LPSTR lpstrCustomFilter;
|
1200
|
+
DWORD nMaxCustFilter;
|
1201
|
+
DWORD nFilterIndex;
|
1202
|
+
LPSTR lpstrFile;
|
1203
|
+
DWORD nMaxFile;
|
1204
|
+
LPSTR lpstrFileTitle;
|
1205
|
+
DWORD nMaxFileTitle;
|
1206
|
+
LPCSTR lpstrInitialDir;
|
1207
|
+
LPCSTR lpstrTitle;
|
1208
|
+
DWORD Flags;
|
1209
|
+
WORD nFileOffset;
|
1210
|
+
WORD nFileExtension;
|
1211
|
+
LPCSTR lpstrDefExt;
|
1212
|
+
LPARAM lCustData;
|
1213
|
+
LPVOID lpfnHook;
|
1214
|
+
LPCSTR lpTemplateName;
|
1215
|
+
//void * pvReserved; // undef for win98 compat
|
1216
|
+
//DWORD dwReserved;
|
1217
|
+
//DWORD FlagsEx;
|
1218
|
+
} OPENFILENAMEA, *LPOPENFILENAMEA;
|
1219
|
+
BOOL WINAPI GetOpenFileNameA(LPOPENFILENAMEA);
|
1220
|
+
BOOL WINAPI GetSaveFileNameA(LPOPENFILENAMEA);
|
1221
|
+
|
1222
|
+
#define SB_HORZ 0
|
1223
|
+
#define SB_VERT 1
|
1224
|
+
#define SB_CTL 2
|
1225
|
+
#define SB_BOTH 3
|
1226
|
+
|
1227
|
+
#define SB_LINEUP 0
|
1228
|
+
#define SB_LINELEFT 0
|
1229
|
+
#define SB_LINEDOWN 1
|
1230
|
+
#define SB_LINERIGHT 1
|
1231
|
+
#define SB_PAGEUP 2
|
1232
|
+
#define SB_PAGELEFT 2
|
1233
|
+
#define SB_PAGEDOWN 3
|
1234
|
+
#define SB_PAGERIGHT 3
|
1235
|
+
#define SB_THUMBPOSITION 4
|
1236
|
+
#define SB_THUMBTRACK 5
|
1237
|
+
#define SB_TOP 6
|
1238
|
+
#define SB_LEFT 6
|
1239
|
+
#define SB_BOTTOM 7
|
1240
|
+
#define SB_RIGHT 7
|
1241
|
+
#define SB_ENDSCROLL 8
|
1242
|
+
|
1243
|
+
#define SIF_RANGE 0x0001
|
1244
|
+
#define SIF_PAGE 0x0002
|
1245
|
+
#define SIF_POS 0x0004
|
1246
|
+
#define SIF_DISABLENOSCROLL 0x0008
|
1247
|
+
#define SIF_TRACKPOS 0x0010
|
1248
|
+
#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
|
1249
|
+
|
1250
|
+
WINUSERAPI
|
1251
|
+
int
|
1252
|
+
WINAPI
|
1253
|
+
SetScrollPos(
|
1254
|
+
__in HWND hWnd,
|
1255
|
+
__in int nBar,
|
1256
|
+
__in int nPos,
|
1257
|
+
__in BOOL bRedraw);
|
1258
|
+
|
1259
|
+
WINUSERAPI
|
1260
|
+
int
|
1261
|
+
WINAPI
|
1262
|
+
GetScrollPos(
|
1263
|
+
__in HWND hWnd,
|
1264
|
+
__in int nBar);
|
1265
|
+
|
1266
|
+
typedef struct tagSCROLLINFO
|
1267
|
+
{
|
1268
|
+
UINT cbSize;
|
1269
|
+
UINT fMask;
|
1270
|
+
int nMin;
|
1271
|
+
int nMax;
|
1272
|
+
UINT nPage;
|
1273
|
+
int nPos;
|
1274
|
+
int nTrackPos;
|
1275
|
+
} SCROLLINFO, *LPSCROLLINFO;
|
1276
|
+
typedef SCROLLINFO CONST *LPCSCROLLINFO;
|
1277
|
+
|
1278
|
+
WINUSERAPI
|
1279
|
+
int
|
1280
|
+
WINAPI
|
1281
|
+
SetScrollInfo(
|
1282
|
+
__in HWND hwnd,
|
1283
|
+
__in int nBar,
|
1284
|
+
__in LPCSCROLLINFO lpsi,
|
1285
|
+
__in BOOL redraw);
|
1286
|
+
|
1287
|
+
WINUSERAPI
|
1288
|
+
BOOL
|
1289
|
+
WINAPI
|
1290
|
+
GetScrollInfo(
|
1291
|
+
__in HWND hwnd,
|
1292
|
+
__in int nBar,
|
1293
|
+
__inout LPSCROLLINFO lpsi);
|
1294
|
+
EOS
|
1295
|
+
|
1296
|
+
new_api_c <<EOS, 'shell32'
|
1297
|
+
typedef HANDLE HDROP;
|
1298
|
+
WINAPI UINT DragQueryFileA(HDROP,UINT,LPSTR,UINT);
|
1299
|
+
WINAPI BOOL DragQueryPoint(HDROP,LPPOINT);
|
1300
|
+
WINAPI void DragFinish(HDROP);
|
1301
|
+
WINAPI void DragAcceptFiles(HWND,BOOL);
|
1302
|
+
EOS
|
1303
|
+
|
1304
|
+
def self.last_error_msg(errno = getlasterror)
|
1305
|
+
message = ' '*512
|
1306
|
+
if formatmessagea(FORMAT_MESSAGE_FROM_SYSTEM, nil, errno, 0, message, message.length, nil) == 0
|
1307
|
+
message = 'unknown error %x' % errno
|
1308
|
+
else
|
1309
|
+
message = message[0, message.index(?\0)] if message.index(?\0)
|
1310
|
+
message.chomp!
|
1311
|
+
end
|
1312
|
+
message
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
def self.setdcbrushcolor(hdc, col)
|
1316
|
+
@@brushes ||= {}
|
1317
|
+
b = @@brushes[col] ||= createsolidbrush(col)
|
1318
|
+
selectobject(hdc, b)
|
1319
|
+
end
|
1320
|
+
def self.setdcpencolor(hdc, col)
|
1321
|
+
@@pens ||= {}
|
1322
|
+
p = @@pens[col] ||= createpen(PS_SOLID, 0, col)
|
1323
|
+
selectobject(hdc, p)
|
1324
|
+
end
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
module Protect
|
1328
|
+
@@lasterror = Time.now
|
1329
|
+
def protect
|
1330
|
+
yield
|
1331
|
+
rescue Object
|
1332
|
+
puts $!.message, $!.backtrace # also dump on stdout, for c/c
|
1333
|
+
delay = Time.now-@@lasterror
|
1334
|
+
sleep 1-delay if delay < 1 # msgbox flood protection
|
1335
|
+
@@lasterror = Time.now
|
1336
|
+
messagebox([$!.message, $!.backtrace].join("\n"), $!.class.name)
|
1337
|
+
end
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
module Msgbox
|
1341
|
+
include Protect
|
1342
|
+
|
1343
|
+
def toplevel
|
1344
|
+
p = self
|
1345
|
+
p = p.parent while p.respond_to? :parent and p.parent
|
1346
|
+
p
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
# shows a message box (non-modal)
|
1350
|
+
# args: message, title/optionhash
|
1351
|
+
def messagebox(*a)
|
1352
|
+
MessageBox.new(toplevel, *a)
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
# asks for user input, yields the result (unless 'cancel' clicked)
|
1356
|
+
# args: prompt, :text => default text, :title => title
|
1357
|
+
def inputbox(*a)
|
1358
|
+
InputBox.new(toplevel, *a) { |*ya| protect { yield(*ya) } }
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
# asks to chose a file to open, yields filename
|
1362
|
+
# args: title, :path => path
|
1363
|
+
def openfile(*a)
|
1364
|
+
OpenFile.new(toplevel, *a) { |*ya| protect { yield(*ya) } }
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
# same as openfile, but for writing a (new) file
|
1368
|
+
def savefile(*a)
|
1369
|
+
SaveFile.new(toplevel, *a) { |*ya| protect { yield(*ya) } }
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
# displays a popup showing a table, yields the selected row
|
1373
|
+
# args: title, [[col0 title, col1 title...], [col0 val0, col1 val0...], [val1], [val2]...]
|
1374
|
+
def listwindow(*a)
|
1375
|
+
ListWindow.new(toplevel, *a) { |*ya| protect { yield(*ya) } }
|
1376
|
+
end
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
class WinWidget
|
1380
|
+
include Msgbox
|
1381
|
+
attr_accessor :parent, :hwnd, :x, :y, :width, :height
|
1382
|
+
|
1383
|
+
def initialize
|
1384
|
+
@parent = nil
|
1385
|
+
@hwnd = nil
|
1386
|
+
@x = @y = @width = @height = 0
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
def grab_focus
|
1390
|
+
return if not @parent
|
1391
|
+
@parent.set_focus(self) if @parent.respond_to? :set_focus
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
def focus?
|
1395
|
+
return true if not @parent
|
1396
|
+
(@parent.respond_to?(:focus?) ? @parent.focus? : true) and
|
1397
|
+
(@parent.respond_to?(:has_focus?) ? @parent.has_focus?(self) : true)
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
def redraw
|
1401
|
+
invalidate(0, 0, @width, @height)
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
def invalidate(x, y, w, h)
|
1405
|
+
x += @x
|
1406
|
+
y += @y
|
1407
|
+
rect = Win32Gui.alloc_c_struct('RECT', :left => x, :right => x+w, :top => y, :bottom => y+h)
|
1408
|
+
Win32Gui.invalidaterect(@hwnd, rect, Win32Gui::FALSE)
|
1409
|
+
end
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
class ContainerChoiceWidget < WinWidget
|
1413
|
+
attr_accessor :views, :view_indexes
|
1414
|
+
def initialize(*a, &b)
|
1415
|
+
@views = {}
|
1416
|
+
@view_indexes = []
|
1417
|
+
@curview = nil
|
1418
|
+
@visible = false
|
1419
|
+
|
1420
|
+
super()
|
1421
|
+
|
1422
|
+
initialize_widget(*a, &b)
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
def initialize_visible_
|
1426
|
+
@visible = true
|
1427
|
+
@views.each { |k, v| v.initialize_visible_ }
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
def view(i)
|
1431
|
+
@views[i]
|
1432
|
+
end
|
1433
|
+
|
1434
|
+
def showview(i)
|
1435
|
+
@curview = @views[i]
|
1436
|
+
@curview.redraw if @curview
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
def addview(name, w)
|
1440
|
+
@view_indexes << name
|
1441
|
+
@views[name] = w
|
1442
|
+
@curview ||= w
|
1443
|
+
w.parent = self
|
1444
|
+
w.hwnd = @hwnd
|
1445
|
+
w.x, w.y, w.width, w.height = @x, @y, @width, @height
|
1446
|
+
w.initialize_visible_ if @visible
|
1447
|
+
w
|
1448
|
+
end
|
1449
|
+
|
1450
|
+
def curview
|
1451
|
+
@curview
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
def curview_index
|
1455
|
+
@views.index(@curview)
|
1456
|
+
end
|
1457
|
+
|
1458
|
+
%w[click click_ctrl mouserelease mousemove rightclick doubleclick mouse_wheel mouse_wheel_ctrl keypress_ keypress_ctrl_].each { |m|
|
1459
|
+
define_method(m) { |*a| @curview.send(m, *a) if @curview and @curview.respond_to? m }
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
def paint_(rc)
|
1463
|
+
@curview.paint_(rc) if @curview
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
def resized_(w, h)
|
1467
|
+
@width = w
|
1468
|
+
@height = h
|
1469
|
+
@views.each { |k, v|
|
1470
|
+
v.x = @x
|
1471
|
+
v.y = @y
|
1472
|
+
v.resized_(w, h)
|
1473
|
+
}
|
1474
|
+
end
|
1475
|
+
|
1476
|
+
def hwnd=(h)
|
1477
|
+
@hwnd = h
|
1478
|
+
@views.each { |k, v| v.hwnd = h }
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
def has_focus?(c)
|
1482
|
+
c == @curview
|
1483
|
+
end
|
1484
|
+
|
1485
|
+
def set_focus(c)
|
1486
|
+
@curview = c
|
1487
|
+
redraw
|
1488
|
+
end
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
class ContainerVBoxWidget < WinWidget
|
1492
|
+
def initialize(*a, &b)
|
1493
|
+
@views = []
|
1494
|
+
@focus_idx = 0
|
1495
|
+
@visible = false
|
1496
|
+
@wantheight = {}
|
1497
|
+
@spacing = 3
|
1498
|
+
@resizing = nil
|
1499
|
+
|
1500
|
+
super()
|
1501
|
+
|
1502
|
+
initialize_widget(*a, &b)
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
def initialize_visible_
|
1506
|
+
@visible = true
|
1507
|
+
@views.each { |v| v.initialize_visible_ }
|
1508
|
+
end
|
1509
|
+
|
1510
|
+
def add(w, opts={})
|
1511
|
+
@views << w
|
1512
|
+
w.parent = self
|
1513
|
+
w.hwnd = @hwnd
|
1514
|
+
resized_(@width, @height)
|
1515
|
+
w.initialize_visible_ if @visible
|
1516
|
+
end
|
1517
|
+
|
1518
|
+
def click(x, y)
|
1519
|
+
cy = 0
|
1520
|
+
pv = []
|
1521
|
+
@views.each_with_index { |v, i|
|
1522
|
+
if y >= cy and y < cy + v.height
|
1523
|
+
if @focus_idx != i
|
1524
|
+
@focus_idx = i
|
1525
|
+
redraw
|
1526
|
+
end
|
1527
|
+
v.click(x, y-v.y) if v.respond_to? :click
|
1528
|
+
return
|
1529
|
+
end
|
1530
|
+
cy += v.height
|
1531
|
+
if y >= cy and y < cy+@spacing
|
1532
|
+
vsz = v
|
1533
|
+
@resizing = v
|
1534
|
+
@wantheight[@resizing] ||= v.height
|
1535
|
+
@tmpwantheight = []
|
1536
|
+
pv.each { |vv| @tmpwantheight << vv if not @wantheight[vv] ; @wantheight[vv] ||= vv.height }
|
1537
|
+
return
|
1538
|
+
end
|
1539
|
+
cy += @spacing
|
1540
|
+
pv << v
|
1541
|
+
}
|
1542
|
+
end
|
1543
|
+
|
1544
|
+
def mousemove(x, y)
|
1545
|
+
if @resizing
|
1546
|
+
@wantheight[@resizing] = [0, y - @resizing.y].max
|
1547
|
+
resized_(@width, @height)
|
1548
|
+
elsif v = @views[@focus_idx]
|
1549
|
+
v.mousemove(x, y-v.y) if v.respond_to? :mousemove
|
1550
|
+
end
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
def mouserelease(x, y)
|
1554
|
+
if @resizing
|
1555
|
+
@wantheight[@resizing] = [0, y - @resizing.y].max
|
1556
|
+
@resizing = nil
|
1557
|
+
@tmpwantheight.each { |vv| @wantheight.delete vv }
|
1558
|
+
@tmpwantheight = nil
|
1559
|
+
resized_(@width, @height)
|
1560
|
+
elsif v = @views[@focus_idx]
|
1561
|
+
v.mouserelease(x, y-v.y) if v.respond_to? :mouserelease
|
1562
|
+
end
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
%w[click_ctrl rightclick doubleclick].each { |m|
|
1566
|
+
define_method(m) { |x, y|
|
1567
|
+
if v = find_view_y(y, true)
|
1568
|
+
v.send(m, x, y-v.y) if v.respond_to? m
|
1569
|
+
end
|
1570
|
+
}
|
1571
|
+
}
|
1572
|
+
|
1573
|
+
%w[mouse_wheel mouse_wheel_ctrl].each { |m|
|
1574
|
+
define_method(m) { |d, x, y|
|
1575
|
+
if v = find_view_y(y, false)
|
1576
|
+
v.send(m, d, x, y-v.y) if v.respond_to? m
|
1577
|
+
end
|
1578
|
+
}
|
1579
|
+
}
|
1580
|
+
%w[keypress_ keypress_ctrl_].each { |m|
|
1581
|
+
define_method(m) { |k|
|
1582
|
+
if v = @views[@focus_idx] and v.respond_to? m
|
1583
|
+
v.send(m, k)
|
1584
|
+
end
|
1585
|
+
}
|
1586
|
+
}
|
1587
|
+
|
1588
|
+
def paint_(hdc)
|
1589
|
+
# TODO check invalidated rectangle
|
1590
|
+
x = @x
|
1591
|
+
y = @y
|
1592
|
+
Win32Gui.selectobject(hdc, Win32Gui.getstockobject(Win32Gui::DC_BRUSH))
|
1593
|
+
Win32Gui.selectobject(hdc, Win32Gui.getstockobject(Win32Gui::DC_PEN))
|
1594
|
+
col = Win32Gui.getsyscolor(Win32Gui::COLOR_BTNFACE)
|
1595
|
+
Win32Gui.setdcbrushcolor(hdc, col)
|
1596
|
+
Win32Gui.setdcpencolor(hdc, col)
|
1597
|
+
@views.each { |v|
|
1598
|
+
v.paint_(hdc) if v.height > 0
|
1599
|
+
y += v.height
|
1600
|
+
Win32Gui.rectangle(hdc, x, y, x+@width, y+@spacing)
|
1601
|
+
y += @spacing
|
1602
|
+
}
|
1603
|
+
Win32Gui.rectangle(hdc, x, y, x+@width, y+@height)
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
def resized_(w, h)
|
1607
|
+
@width = w
|
1608
|
+
@height = h
|
1609
|
+
x = @x
|
1610
|
+
y = @y
|
1611
|
+
freesize = h
|
1612
|
+
freesize -= @spacing*(@views.length-1)
|
1613
|
+
nrfree = 0
|
1614
|
+
@views.each { |v|
|
1615
|
+
if @wantheight[v]
|
1616
|
+
freesize -= @wantheight[v]
|
1617
|
+
else
|
1618
|
+
nrfree += 1
|
1619
|
+
end
|
1620
|
+
}
|
1621
|
+
freesize = 0 if freesize < 0
|
1622
|
+
@views.each { |v|
|
1623
|
+
v.x = x
|
1624
|
+
v.y = y
|
1625
|
+
ch = @wantheight[v] || freesize/nrfree
|
1626
|
+
v.resized_(w, ch)
|
1627
|
+
y += ch + @spacing
|
1628
|
+
}
|
1629
|
+
redraw
|
1630
|
+
end
|
1631
|
+
|
1632
|
+
def find_view_y(ty, update_focus=false)
|
1633
|
+
y = 0
|
1634
|
+
@views.each_with_index { |v, i|
|
1635
|
+
if ty >= y and ty < y + v.height
|
1636
|
+
if update_focus and @focus_idx != i
|
1637
|
+
@focus_idx = i
|
1638
|
+
redraw
|
1639
|
+
end
|
1640
|
+
return v
|
1641
|
+
end
|
1642
|
+
y += v.height + @spacing
|
1643
|
+
}
|
1644
|
+
nil
|
1645
|
+
end
|
1646
|
+
|
1647
|
+
def hwnd=(h)
|
1648
|
+
@hwnd = h
|
1649
|
+
@views.each { |v| v.hwnd = h }
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
def resize_child(cld, w, h)
|
1653
|
+
return if @wantheight[cld] == h
|
1654
|
+
if h < 0
|
1655
|
+
@wantheight.delete cld
|
1656
|
+
else
|
1657
|
+
@wantheight[cld] = h
|
1658
|
+
end
|
1659
|
+
resized_(@width, @height)
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
def has_focus?(c)
|
1663
|
+
c == @views[@focus_idx]
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
def set_focus(c)
|
1667
|
+
@focus_idx = @views.index(c)
|
1668
|
+
redraw
|
1669
|
+
end
|
1670
|
+
end
|
1671
|
+
|
1672
|
+
module TextWidget
|
1673
|
+
attr_accessor :caret_x, :caret_y, :hl_word, :font_width, :font_height
|
1674
|
+
|
1675
|
+
def initialize_text
|
1676
|
+
@caret_x = @caret_y = 0 # text cursor position
|
1677
|
+
@oldcaret_x = @oldcaret_y = 1
|
1678
|
+
@font_width = @font_height = 1
|
1679
|
+
@hl_word = nil
|
1680
|
+
end
|
1681
|
+
|
1682
|
+
def update_hl_word(line, offset)
|
1683
|
+
return if not line
|
1684
|
+
word = line[0...offset].to_s[/\w*$/] << line[offset..-1].to_s[/^\w*/]
|
1685
|
+
word = nil if word == ''
|
1686
|
+
@hl_word = word if @hl_word != word
|
1687
|
+
end
|
1688
|
+
|
1689
|
+
def set_caret_from_click(x, y)
|
1690
|
+
@caret_x = (x-1).to_i / @font_width
|
1691
|
+
@caret_y = y.to_i / @font_height
|
1692
|
+
update_caret
|
1693
|
+
end
|
1694
|
+
|
1695
|
+
def invalidate_caret(cx, cy, x=0, y=0)
|
1696
|
+
invalidate(x + cx*@font_width, y + cy*@font_height, 2, @font_height)
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
def clipboard_copy(buf)
|
1700
|
+
Win32Gui.openclipboard(@hwnd)
|
1701
|
+
Win32Gui.emptyclipboard
|
1702
|
+
if buf and not buf.empty?
|
1703
|
+
h = Win32Gui.globalalloc(Win32Gui::GMEM_MOVEABLE, buf.length+1)
|
1704
|
+
ptr = Win32Gui.globallock(h)
|
1705
|
+
Win32Gui.memory_write(ptr, buf)
|
1706
|
+
Win32Gui.globalunlock(h)
|
1707
|
+
Win32Gui.setclipboarddata(Win32Gui::CF_TEXT, h)
|
1708
|
+
# on(WM_DESTROYCLIPBOARD) { Win32Gui.globalfree(h) }
|
1709
|
+
end
|
1710
|
+
Win32Gui.closeclipboard
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
def clipboard_paste
|
1714
|
+
Win32Gui.openclipboard(@hwnd)
|
1715
|
+
h = Win32Gui.getclipboarddata(Win32Gui::CF_TEXT)
|
1716
|
+
if h and h != 0 and h != Win32Gui::GMEM_INVALID_HANDLE
|
1717
|
+
sz = Win32Gui.globalsize(h)
|
1718
|
+
ptr = Win32Gui.globallock(h)
|
1719
|
+
buf = Win32Gui.memory_read(ptr, sz)
|
1720
|
+
Win32Gui.globalunlock(h)
|
1721
|
+
Win32Gui.closeclipboard
|
1722
|
+
buf.chomp(0.chr)
|
1723
|
+
end
|
1724
|
+
end
|
1725
|
+
|
1726
|
+
def set_font(todo)
|
1727
|
+
hdc = Win32Gui.getdc(@hwnd)
|
1728
|
+
# selectobject(hdc, hfont)
|
1729
|
+
sz = Win32Gui.alloc_c_struct('POINT')
|
1730
|
+
Win32Gui.gettextextentpoint32a(hdc, 'x', 1, sz)
|
1731
|
+
@font_width = sz[:x]
|
1732
|
+
@font_height = sz[:y]
|
1733
|
+
Win32Gui.releasedc(@hwnd, hdc)
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
class DrawableWidget < WinWidget
|
1738
|
+
include TextWidget
|
1739
|
+
|
1740
|
+
attr_accessor :buttons
|
1741
|
+
|
1742
|
+
def initialize(*a, &b)
|
1743
|
+
@color = {}
|
1744
|
+
@default_color_association = { :background => :winbg }
|
1745
|
+
@buttons = nil
|
1746
|
+
|
1747
|
+
super()
|
1748
|
+
|
1749
|
+
initialize_text
|
1750
|
+
initialize_widget(*a, &b)
|
1751
|
+
end
|
1752
|
+
|
1753
|
+
def initialize_widget
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
def initialize_visible_
|
1757
|
+
{ :white => 'fff', :palegrey => 'ddd', :black => '000', :grey => '444',
|
1758
|
+
:red => 'f00', :darkred => '800', :palered => 'fcc',
|
1759
|
+
:green => '0f0', :darkgreen => '080', :palegreen => 'cfc',
|
1760
|
+
:blue => '00f', :darkblue => '008', :paleblue => 'ccf',
|
1761
|
+
:yellow => 'ff0', :darkyellow => '440', :paleyellow => 'ffc',
|
1762
|
+
}.each { |tag, val|
|
1763
|
+
@color[tag] = color(val)
|
1764
|
+
}
|
1765
|
+
@color[:winbg] = Win32Gui.getsyscolor(Win32Gui::COLOR_BTNFACE)
|
1766
|
+
set_color_association(@default_color_association) # should be called after Gui.main
|
1767
|
+
set_font('courier 10')
|
1768
|
+
initialize_visible if respond_to? :initialize_visible
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
def set_color_association(h)
|
1772
|
+
h.each { |k, v| @color[k] = color(v) }
|
1773
|
+
gui_update
|
1774
|
+
end
|
1775
|
+
|
1776
|
+
def paint_(realhdc)
|
1777
|
+
@hdc = Win32Gui.createcompatibledc(realhdc)
|
1778
|
+
bmp = Win32Gui.createcompatiblebitmap(realhdc, @width, @height)
|
1779
|
+
Win32Gui.selectobject(@hdc, bmp)
|
1780
|
+
Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::DC_BRUSH))
|
1781
|
+
Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::DC_PEN))
|
1782
|
+
Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::ANSI_FIXED_FONT))
|
1783
|
+
Win32Gui.setbkmode(@hdc, Win32Gui::TRANSPARENT)
|
1784
|
+
draw_rectangle_color(:background, 0, 0, @width, @height)
|
1785
|
+
paint
|
1786
|
+
Win32Gui.bitblt(realhdc, @x, @y, @width, @height, @hdc, 0, 0, Win32Gui::SRCCOPY)
|
1787
|
+
Win32Gui.deleteobject(bmp)
|
1788
|
+
Win32Gui.deletedc(@hdc)
|
1789
|
+
@hdc = nil
|
1790
|
+
end
|
1791
|
+
|
1792
|
+
def resized_(w, h)
|
1793
|
+
@width = w
|
1794
|
+
@height = h
|
1795
|
+
resized(w, h) if respond_to? :resized
|
1796
|
+
end
|
1797
|
+
|
1798
|
+
def keypress_(key)
|
1799
|
+
# XXX my gtk api sux
|
1800
|
+
if not respond_to? :keypress or not protect { keypress(key) }
|
1801
|
+
protect { @parent.keypress(key) } if @parent.respond_to? :keypress
|
1802
|
+
end
|
1803
|
+
end
|
1804
|
+
|
1805
|
+
def keypress_ctrl_(key)
|
1806
|
+
if not respond_to? :keypress_ctrl or not protect { keypress_ctrl(key) }
|
1807
|
+
protect { @parent.keypress_ctrl(key) } if @parent.respond_to? :keypress_ctrl
|
1808
|
+
end
|
1809
|
+
end
|
1810
|
+
|
1811
|
+
def gui_update
|
1812
|
+
redraw
|
1813
|
+
end
|
1814
|
+
|
1815
|
+
def color(col)
|
1816
|
+
@color[col] ||= col.sub(/^(\w)(\w)(\w)$/, '\\3\\3\\2\\2\\1\\1').to_i(16)
|
1817
|
+
end
|
1818
|
+
|
1819
|
+
def draw_color(col)
|
1820
|
+
col = color(col)
|
1821
|
+
Win32Gui.settextcolor(@hdc, col)
|
1822
|
+
Win32Gui.setdcpencolor(@hdc, col)
|
1823
|
+
Win32Gui.setdcbrushcolor(@hdc, col)
|
1824
|
+
end
|
1825
|
+
|
1826
|
+
def draw_line(x, y, ex, ey)
|
1827
|
+
Win32Gui.movetoex(@hdc, x, y, 0)
|
1828
|
+
Win32Gui.lineto(@hdc, ex, ey)
|
1829
|
+
end
|
1830
|
+
|
1831
|
+
def draw_line_color(col, x, y, ex, ey)
|
1832
|
+
Win32Gui.setdcpencolor(@hdc, color(col))
|
1833
|
+
draw_line(x, y, ex, ey)
|
1834
|
+
end
|
1835
|
+
|
1836
|
+
def draw_rectangle(x, y, w, h)
|
1837
|
+
Win32Gui.rectangle(@hdc, x, y, x+w, y+h)
|
1838
|
+
end
|
1839
|
+
|
1840
|
+
def draw_rectangle_color(col, x, y, w, h)
|
1841
|
+
Win32Gui.setdcbrushcolor(@hdc, color(col))
|
1842
|
+
Win32Gui.setdcpencolor(@hdc, color(col)) # rect border
|
1843
|
+
draw_rectangle(x, y, w, h)
|
1844
|
+
end
|
1845
|
+
|
1846
|
+
def draw_string(x, y, text)
|
1847
|
+
return if not text or text == ''
|
1848
|
+
Win32Gui.textouta(@hdc, x, y, text, text.length)
|
1849
|
+
end
|
1850
|
+
|
1851
|
+
def draw_string_color(col, x, y, text)
|
1852
|
+
Win32Gui.settextcolor(@hdc, color(col))
|
1853
|
+
draw_string(x, y, text)
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
def keyboard_state(query=nil)
|
1857
|
+
case query
|
1858
|
+
when :control, :ctrl
|
1859
|
+
Win32Gui.getkeystate(Win32Gui::VK_CONTROL) & 0x8000 > 0
|
1860
|
+
when :shift
|
1861
|
+
Win32Gui.getkeystate(Win32Gui::VK_SHIFT) & 0x8000 > 0
|
1862
|
+
when :alt
|
1863
|
+
Win32Gui.getkeystate(Win32Gui::VK_MENU) & 0x8000 > 0
|
1864
|
+
else
|
1865
|
+
[:control, :shift, :alt].find_all { |s| keyboard_state(s) }
|
1866
|
+
end
|
1867
|
+
end
|
1868
|
+
|
1869
|
+
# represents a clickable area with a label (aka button)
|
1870
|
+
class Button
|
1871
|
+
attr_accessor :x, :y, :w, :h, :c1, :c2, :text, :down, :action
|
1872
|
+
|
1873
|
+
# create a new Button with the specified text & border color
|
1874
|
+
def initialize(text='Ok', c1=:palegrey, c2=:grey, &b)
|
1875
|
+
@x = @y = @w = @h = 0
|
1876
|
+
@c1, @c2 = c1, c2
|
1877
|
+
@text = text
|
1878
|
+
@down = false
|
1879
|
+
@action = b
|
1880
|
+
end
|
1881
|
+
|
1882
|
+
# move the button (x y w h)
|
1883
|
+
def move(nx=@x, ny=@y, nw=@w, nh=@h)
|
1884
|
+
@x, @y, @w, @h = nx, ny, nw, nh
|
1885
|
+
end
|
1886
|
+
|
1887
|
+
# draw the button on the parent widget
|
1888
|
+
def paint(w)
|
1889
|
+
c1, c2 = @c1, @c2
|
1890
|
+
c1, c2 = c2, c1 if @down
|
1891
|
+
w.draw_string_color(:text, @x+(@w-w.font_width*@text.length)/2, @y+(@h - w.font_height)/2, @text)
|
1892
|
+
w.draw_line_color(c1, @x, @y, @x, @y+@h)
|
1893
|
+
w.draw_line_color(c1, @x, @y, @x+@w, @y)
|
1894
|
+
w.draw_line_color(c2, @x+@w, @y+@h, @x, @y+@h)
|
1895
|
+
w.draw_line_color(c2, @x+@w, @y+@h, @x+@w, @y)
|
1896
|
+
end
|
1897
|
+
|
1898
|
+
# checks if the click is on the button, returns true if so
|
1899
|
+
def click(x, y)
|
1900
|
+
@down = true if x >= @x and x < @x+@w and y >= @y and y < @y+@h
|
1901
|
+
end
|
1902
|
+
|
1903
|
+
def mouserelease(x, y)
|
1904
|
+
if @down
|
1905
|
+
@down = false
|
1906
|
+
@action.call
|
1907
|
+
true
|
1908
|
+
end
|
1909
|
+
end
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
# add a new button to the widget
|
1913
|
+
def add_button(text='Ok', *a, &b)
|
1914
|
+
@buttons ||= []
|
1915
|
+
@buttons << Button.new(text, *a, &b)
|
1916
|
+
end
|
1917
|
+
|
1918
|
+
# render the buttons on the widget
|
1919
|
+
# should be called during #paint
|
1920
|
+
def paint_buttons
|
1921
|
+
@buttons.each { |b| b.paint(self) }
|
1922
|
+
end
|
1923
|
+
|
1924
|
+
# checks if the click is inside a button, returns true if it is
|
1925
|
+
# should be called during #click
|
1926
|
+
def click_buttons(x, y)
|
1927
|
+
@buttons.find { |b| b.click(x, y) }
|
1928
|
+
end
|
1929
|
+
|
1930
|
+
# the mouse was released, call button action if it is pressed
|
1931
|
+
# should be called during #mouserelease
|
1932
|
+
def mouserelease_buttons(x, y)
|
1933
|
+
@buttons.find { |b| b.mouserelease(x, y) }
|
1934
|
+
end
|
1935
|
+
end
|
1936
|
+
|
1937
|
+
class Window
|
1938
|
+
include Msgbox
|
1939
|
+
|
1940
|
+
attr_accessor :menu, :hwnd, :popups
|
1941
|
+
def initialize(*a, &b)
|
1942
|
+
@widget = nil
|
1943
|
+
@controlid = 1 # next free control id for menu items, buttons etc
|
1944
|
+
@control_action = {}
|
1945
|
+
(@@mainwindow_list ||= []) << self
|
1946
|
+
@visible = false
|
1947
|
+
@popups = []
|
1948
|
+
@parent ||= nil
|
1949
|
+
|
1950
|
+
cname = "metasm_w32gui_#{object_id}"
|
1951
|
+
cls = Win32Gui.alloc_c_struct 'WNDCLASSEXA', :cbsize => :size,
|
1952
|
+
:style => Win32Gui::CS_DBLCLKS,
|
1953
|
+
:hcursor => Win32Gui.loadcursora(0, Win32Gui::IDC_ARROW),
|
1954
|
+
:lpszclassname => cname,
|
1955
|
+
:lpfnwndproc => Win32Gui.callback_alloc_c('__stdcall int wndproc(int, int, int, int)') { |hwnd, msg, wp, lp| windowproc(hwnd, msg, wp, lp) }
|
1956
|
+
|
1957
|
+
Win32Gui.registerclassexa(cls)
|
1958
|
+
|
1959
|
+
@hwnd = Win32Gui.createwindowexa(win32styleex, cname, 'win32gui window', win32style, Win32Gui::CW_USEDEFAULT, Win32Gui::SW_HIDE, Win32Gui::CW_USEDEFAULT, 0, 0, 0, 0, 0)
|
1960
|
+
|
1961
|
+
initialize_window(*a, &b)
|
1962
|
+
|
1963
|
+
if respond_to? :build_menu
|
1964
|
+
@menu = []
|
1965
|
+
@menuhwnd = 0
|
1966
|
+
build_menu
|
1967
|
+
update_menu
|
1968
|
+
end
|
1969
|
+
|
1970
|
+
Win32Gui.dragacceptfiles(@hwnd, Win32Gui::TRUE)
|
1971
|
+
|
1972
|
+
show
|
1973
|
+
end
|
1974
|
+
def win32styleex; 0 ; end
|
1975
|
+
def win32style; Win32Gui::WS_OVERLAPPEDWINDOW ; end
|
1976
|
+
|
1977
|
+
def show
|
1978
|
+
Win32Gui.showwindow(@hwnd, Win32Gui::SW_SHOWDEFAULT)
|
1979
|
+
Win32Gui.updatewindow(@hwnd)
|
1980
|
+
end
|
1981
|
+
|
1982
|
+
def keyboard_state(query=nil)
|
1983
|
+
case query
|
1984
|
+
when :control, :ctrl
|
1985
|
+
Win32Gui.getkeystate(Win32Gui::VK_CONTROL) & 0x8000 > 0
|
1986
|
+
when :shift
|
1987
|
+
Win32Gui.getkeystate(Win32Gui::VK_SHIFT) & 0x8000 > 0
|
1988
|
+
when :alt
|
1989
|
+
Win32Gui.getkeystate(Win32Gui::VK_MENU) & 0x8000 > 0
|
1990
|
+
end
|
1991
|
+
end
|
1992
|
+
|
1993
|
+
# keypress event keyval traduction table
|
1994
|
+
Keyboard_trad = Win32Gui.cp.lexer.definition.keys.grep(/^VK_/).inject({}) { |h, cst|
|
1995
|
+
v = Win32Gui.const_get(cst)
|
1996
|
+
key = cst.to_s.sub(/^VK_/, '').downcase.to_sym
|
1997
|
+
h.update v => {
|
1998
|
+
:prior => :pgup, :next => :pgdown,
|
1999
|
+
:escape => :esc, :return => :enter,
|
2000
|
+
:back => :backspace,
|
2001
|
+
}.fetch(key, key)
|
2002
|
+
}
|
2003
|
+
|
2004
|
+
#MSGNAME = Win32Gui.cp.lexer.definition.keys.grep(/WM_/).sort.inject({}) { |h, c| h.update Win32Gui.const_get(c) => c }
|
2005
|
+
def windowproc(hwnd, msg, wparam, lparam)
|
2006
|
+
#puts "wproc #{'%x' % hwnd} #{MSGNAME[msg] || msg} #{'%x' % wparam} #{'%x' % lparam}" if not %w[WM_NCHITTEST WM_SETCURSOR WM_MOUSEMOVE WM_NCMOUSEMOVE].include? MSGNAME[msg]
|
2007
|
+
@hwnd ||= hwnd # some messages are sent before createwin returns
|
2008
|
+
case msg
|
2009
|
+
when Win32Gui::WM_NCHITTEST, Win32Gui::WM_SETCURSOR
|
2010
|
+
# most frequent messages (with MOUSEMOVE)
|
2011
|
+
return Win32Gui.defwindowproca(hwnd, msg, wparam, lparam)
|
2012
|
+
when Win32Gui::WM_MOUSEMOVE, Win32Gui::WM_LBUTTONDOWN, Win32Gui::WM_RBUTTONDOWN,
|
2013
|
+
Win32Gui::WM_LBUTTONDBLCLK, Win32Gui::WM_MOUSEWHEEL, Win32Gui::WM_LBUTTONUP
|
2014
|
+
mouse_msg(msg, wparam, lparam)
|
2015
|
+
when Win32Gui::WM_PAINT
|
2016
|
+
ps = Win32Gui.alloc_c_struct('PAINTSTRUCT')
|
2017
|
+
hdc = Win32Gui.beginpaint(hwnd, ps)
|
2018
|
+
if @widget
|
2019
|
+
@widget.paint_(hdc)
|
2020
|
+
else
|
2021
|
+
Win32Gui.selectobject(hdc, Win32Gui.getstockobject(Win32Gui::DC_BRUSH))
|
2022
|
+
Win32Gui.selectobject(hdc, Win32Gui.getstockobject(Win32Gui::DC_PEN))
|
2023
|
+
col = Win32Gui.getsyscolor(Win32Gui::COLOR_BTNFACE)
|
2024
|
+
Win32Gui.setdcbrushcolor(hdc, col)
|
2025
|
+
Win32Gui.setdcpencolor(hdc, col)
|
2026
|
+
Win32Gui.rectangle(hdc, 0, 0, @width, @height)
|
2027
|
+
end
|
2028
|
+
Win32Gui.endpaint(hwnd, ps)
|
2029
|
+
when Win32Gui::WM_MOVE
|
2030
|
+
rect = Win32Gui.alloc_c_struct('RECT')
|
2031
|
+
Win32Gui.getwindowrect(@hwnd, rect)
|
2032
|
+
@x, @y, @width, @height = rect[:left], rect[:top], rect[:right]-rect[:left], rect[:bottom]-rect[:top]
|
2033
|
+
@clientx = lparam & 0xffff
|
2034
|
+
@clienty = (lparam >> 16) & 0xffff
|
2035
|
+
when Win32Gui::WM_SIZE
|
2036
|
+
rect = Win32Gui.alloc_c_struct('RECT')
|
2037
|
+
Win32Gui.getwindowrect(@hwnd, rect)
|
2038
|
+
@x, @y, @width, @height = rect[:left], rect[:top], rect[:right]-rect[:left], rect[:bottom]-rect[:top]
|
2039
|
+
@clientwidth = lparam & 0xffff
|
2040
|
+
@clientheight = (lparam >> 16) & 0xffff
|
2041
|
+
@widget.resized_(lparam & 0xffff, (lparam >> 16) & 0xffff) if @widget
|
2042
|
+
redraw
|
2043
|
+
when Win32Gui::WM_WINDOWPOSCHANGING
|
2044
|
+
if @popups.first
|
2045
|
+
# must move popups to top before updating hwndInsertafter
|
2046
|
+
f = Win32Gui::SWP_NOACTIVATE | Win32Gui::SWP_NOMOVE | Win32Gui::SWP_NOSIZE |
|
2047
|
+
Win32Gui::SWP_NOOWNERZORDER | Win32Gui::SWP_NOSENDCHANGING
|
2048
|
+
@popups.each { |pw| Win32Gui.setwindowpos(pw.hwnd, Win32Gui::HWND_TOP, 0, 0, 0, 0, f) }
|
2049
|
+
Win32Gui.memory_write_int(lparam+Win32Gui.cp.typesize[:ptr], @popups.first.hwnd)
|
2050
|
+
end
|
2051
|
+
when Win32Gui::WM_SHOWWINDOW
|
2052
|
+
initialize_visible_
|
2053
|
+
when Win32Gui::WM_KEYDOWN, Win32Gui::WM_SYSKEYDOWN
|
2054
|
+
# SYSKEYDOWN for f10 (default = activate the menu bar)
|
2055
|
+
if key = Keyboard_trad[wparam]
|
2056
|
+
if keyboard_state(:control)
|
2057
|
+
@widget.keypress_ctrl_(key) if @widget
|
2058
|
+
else
|
2059
|
+
@widget.keypress_(key) if @widget
|
2060
|
+
end
|
2061
|
+
end
|
2062
|
+
Win32Gui.defwindowproca(hwnd, msg, wparam, lparam) if key != :f10 # alt+f4 etc
|
2063
|
+
when Win32Gui::WM_CHAR
|
2064
|
+
if keyboard_state(:control) and not keyboard_state(:alt) # altgr+[ returns CTRL on..
|
2065
|
+
if ?a.kind_of?(String)
|
2066
|
+
wparam += (keyboard_state(:shift) ? ?A.ord : ?a.ord) - 1 if wparam < 0x1a
|
2067
|
+
k = wparam.chr
|
2068
|
+
else
|
2069
|
+
wparam += (keyboard_state(:shift) ? ?A : ?a) - 1 if wparam < 0x1a
|
2070
|
+
k = wparam
|
2071
|
+
end
|
2072
|
+
@widget.keypress_ctrl_(k) if @widget
|
2073
|
+
else
|
2074
|
+
k = (?a.kind_of?(String) ? wparam.chr : wparam)
|
2075
|
+
@widget.keypress_(k) if @widget
|
2076
|
+
end
|
2077
|
+
when Win32Gui::WM_DESTROY
|
2078
|
+
destroy_window
|
2079
|
+
when Win32Gui::WM_COMMAND
|
2080
|
+
if a = @control_action[wparam]
|
2081
|
+
protect { a.call }
|
2082
|
+
end
|
2083
|
+
when Win32Gui::WM_DROPFILES
|
2084
|
+
cnt = Win32Gui.dragqueryfilea(wparam, -1, 0, 0)
|
2085
|
+
cnt.times { |i|
|
2086
|
+
buf = [0].pack('C')*1024
|
2087
|
+
len = Win32Gui.dragqueryfilea(wparam, i, buf, buf.length)
|
2088
|
+
protect { @widget.dragdropfile(buf[0, len]) } if @widget and @widget.respond_to? :dragdropfile
|
2089
|
+
}
|
2090
|
+
Win32Gui.dragfinish(wparam)
|
2091
|
+
else return Win32Gui.defwindowproca(hwnd, msg, wparam, lparam)
|
2092
|
+
end
|
2093
|
+
0
|
2094
|
+
end
|
2095
|
+
|
2096
|
+
def mouse_msg(msg, wparam, lparam)
|
2097
|
+
return if not @widget
|
2098
|
+
x = Expression.make_signed(lparam & 0xffff, 16)
|
2099
|
+
y = Expression.make_signed((lparam >> 16) & 0xffff, 16)
|
2100
|
+
ctrl = true if wparam & Win32Gui::MK_CONTROL > 0
|
2101
|
+
cmsg =
|
2102
|
+
case msg
|
2103
|
+
when Win32Gui::WM_MOUSEMOVE
|
2104
|
+
:mousemove
|
2105
|
+
when Win32Gui::WM_LBUTTONDOWN
|
2106
|
+
ctrl ? :click_ctrl : :click
|
2107
|
+
when Win32Gui::WM_LBUTTONUP
|
2108
|
+
:mouserelease
|
2109
|
+
when Win32Gui::WM_RBUTTONDOWN
|
2110
|
+
:rightclick
|
2111
|
+
when Win32Gui::WM_LBUTTONDBLCLK
|
2112
|
+
:doubleclick
|
2113
|
+
when Win32Gui::WM_MOUSEWHEEL
|
2114
|
+
off = Expression.make_signed((wparam >> 16) & 0xffff, 16)
|
2115
|
+
dir = off > 0 ? :up : :down
|
2116
|
+
if ctrl
|
2117
|
+
return(@widget.mouse_wheel_ctrl(dir, x-@clientx, y-@clienty) if @widget.respond_to? :mouse_wheel_ctrl)
|
2118
|
+
else
|
2119
|
+
return(@widget.mouse_wheel(dir, x-@clientx, y-@clienty) if @widget.respond_to? :mouse_wheel)
|
2120
|
+
end
|
2121
|
+
end
|
2122
|
+
|
2123
|
+
case cmsg
|
2124
|
+
when :click
|
2125
|
+
Win32Gui.setcapture(@hwnd)
|
2126
|
+
when :mouserelease
|
2127
|
+
Win32Gui.releasecapture
|
2128
|
+
end
|
2129
|
+
|
2130
|
+
@widget.send(cmsg, x, y) if cmsg and @widget.respond_to? cmsg
|
2131
|
+
end
|
2132
|
+
|
2133
|
+
def initialize_visible_
|
2134
|
+
return if @visible
|
2135
|
+
@visible = true
|
2136
|
+
@widget.initialize_visible_ if @widget
|
2137
|
+
end
|
2138
|
+
|
2139
|
+
attr_reader :x, :y, :width, :height
|
2140
|
+
attr_reader :clientx, :clienty, :clientwidth, :clientheight
|
2141
|
+
def x=(newx)
|
2142
|
+
Win32Gui.movewindow(@hwnd, newx, @y, @width, @height, Win32Gui::TRUE)
|
2143
|
+
end
|
2144
|
+
def y=(newy)
|
2145
|
+
Win32Gui.movewindow(@hwnd, @x, newy, @width, @height, Win32Gui::TRUE)
|
2146
|
+
end
|
2147
|
+
def width=(newwidth)
|
2148
|
+
Win32Gui.movewindow(@hwnd, @x, @y, newwidth, @height, Win32Gui::TRUE)
|
2149
|
+
end
|
2150
|
+
def height=(newheight)
|
2151
|
+
Win32Gui.movewindow(@hwnd, @x, @y, @width, newheight, Win32Gui::TRUE)
|
2152
|
+
end
|
2153
|
+
|
2154
|
+
def widget ; @widget ; end
|
2155
|
+
def widget=(w)
|
2156
|
+
@widget = w
|
2157
|
+
w.hwnd = @hwnd if w
|
2158
|
+
w.parent = self if w
|
2159
|
+
if @visible and w
|
2160
|
+
@widget.initialize_visible_
|
2161
|
+
rect = Win32Gui.alloc_c_struct('RECT')
|
2162
|
+
Win32Gui.getclientrect(@hwnd, rect)
|
2163
|
+
@widget.resized_(rect[:right], rect[:bottom])
|
2164
|
+
end
|
2165
|
+
redraw
|
2166
|
+
end
|
2167
|
+
|
2168
|
+
def redraw
|
2169
|
+
Win32Gui.invalidaterect(@hwnd, 0, Win32Gui::FALSE)
|
2170
|
+
end
|
2171
|
+
|
2172
|
+
def destroy
|
2173
|
+
Win32Gui.sendmessagea(@hwnd, Win32Gui::WM_CLOSE, 0, 0)
|
2174
|
+
end
|
2175
|
+
|
2176
|
+
def destroy_window
|
2177
|
+
@destroyed = true
|
2178
|
+
@@mainwindow_list.delete self
|
2179
|
+
Gui.main_quit if @@mainwindow_list.empty? # XXX we didn't call Gui.main, we shouldn't Gui.main_quit...
|
2180
|
+
end
|
2181
|
+
|
2182
|
+
def destroyed? ; @destroyed ||= false ; end
|
2183
|
+
|
2184
|
+
def new_menu
|
2185
|
+
[]
|
2186
|
+
end
|
2187
|
+
|
2188
|
+
# finds a menu by name (recursive)
|
2189
|
+
# returns a valid arg for addsubmenu(ret)
|
2190
|
+
def find_menu(name, from=@menu)
|
2191
|
+
name = name.gsub('_', '')
|
2192
|
+
if not l = from.find { |e| e.grep(::String).find { |es| es.gsub('_', '') == name } }
|
2193
|
+
l = from.map { |e| e.grep(::Array).map { |ae| find_menu(name, ae) }.compact.first }.compact.first
|
2194
|
+
end
|
2195
|
+
l.grep(::Array).first if l
|
2196
|
+
end
|
2197
|
+
|
2198
|
+
# append stuff to a menu
|
2199
|
+
# arglist:
|
2200
|
+
# empty = menu separator
|
2201
|
+
# string = menu entry display name (use a single '_' keyboard for shortcut, eg 'Sho_rtcut' => 'r')
|
2202
|
+
# :check = menu entry is a checkbox type, add a true/false argument to specify initial value
|
2203
|
+
# second string = keyboard shortcut (accelerator) - use '^' for Ctrl, and '<up>' for special keys
|
2204
|
+
# a menu object = this entry will open a submenu (you must specify a name, and action is ignored)
|
2205
|
+
# the method takes a block or a Proc argument that will be run whenever the menu item is selected
|
2206
|
+
#
|
2207
|
+
# use @menu to reference the top-level menu bar
|
2208
|
+
# call update_menu when the menu is done
|
2209
|
+
def addsubmenu(menu, *args, &action)
|
2210
|
+
args << action if action
|
2211
|
+
menu << args
|
2212
|
+
menu.last
|
2213
|
+
end
|
2214
|
+
|
2215
|
+
# make the window's MenuBar reflect the content of @menu
|
2216
|
+
def update_menu
|
2217
|
+
Win32Gui.destroymenu(@menuhwnd) if @menuhwnd != 0
|
2218
|
+
@menuhwnd = Win32Gui.createmenu()
|
2219
|
+
@menu.each { |e| create_menu_item(@menuhwnd, e) }
|
2220
|
+
Win32Gui.setmenu(@hwnd, @menuhwnd)
|
2221
|
+
end
|
2222
|
+
|
2223
|
+
def create_menu_item(menu, entry)
|
2224
|
+
args = entry.dup
|
2225
|
+
|
2226
|
+
stock = (%w[OPEN SAVE CLOSE QUIT] & args).first
|
2227
|
+
args.delete stock if stock
|
2228
|
+
accel = args.grep(/^\^?(\w|<\w+>)$/).first
|
2229
|
+
args.delete accel if accel
|
2230
|
+
check = args.delete :check
|
2231
|
+
action = args.grep(::Proc).first
|
2232
|
+
args.delete action if action
|
2233
|
+
if submenu = args.grep(::Array).first
|
2234
|
+
args.delete submenu
|
2235
|
+
sm = Win32Gui.createmenu()
|
2236
|
+
submenu.each { |e| create_menu_item(sm, e) }
|
2237
|
+
submenu = sm
|
2238
|
+
end
|
2239
|
+
label = args.shift
|
2240
|
+
|
2241
|
+
label ||= '_' + stock.capitalize if stock
|
2242
|
+
|
2243
|
+
flags = 0
|
2244
|
+
|
2245
|
+
if check
|
2246
|
+
checked = args.shift
|
2247
|
+
flags |= (checked ? Win32Gui::MF_CHECKED : Win32Gui::MF_UNCHECKED)
|
2248
|
+
end
|
2249
|
+
flags |= Win32Gui::MF_POPUP if submenu
|
2250
|
+
if label
|
2251
|
+
flags |= Win32Gui::MF_STRING
|
2252
|
+
label = label.gsub('&', '&&')
|
2253
|
+
label = label.tr('_', '&')
|
2254
|
+
else
|
2255
|
+
flags |= Win32Gui::MF_SEPARATOR
|
2256
|
+
end
|
2257
|
+
|
2258
|
+
if accel
|
2259
|
+
key = accel[-1]
|
2260
|
+
key = accel[/<(.*)>/, 1] if key == ?>
|
2261
|
+
label += "\t#{'c-' if accel[0] == ?^}#{key.kind_of?(Integer) ? key.chr : key}"
|
2262
|
+
end
|
2263
|
+
|
2264
|
+
if action
|
2265
|
+
id = @controlid
|
2266
|
+
if not check
|
2267
|
+
@control_action[id] = action
|
2268
|
+
else
|
2269
|
+
@control_action[id] = lambda {
|
2270
|
+
checked = action.call(!checked)
|
2271
|
+
Win32Gui.checkmenuitem(menu, id, (checked ? Win32Gui::MF_CHECKED : Win32Gui::MF_UNCHECKED))
|
2272
|
+
}
|
2273
|
+
end
|
2274
|
+
@controlid += 1
|
2275
|
+
end
|
2276
|
+
|
2277
|
+
Win32Gui.appendmenua(menu, flags, id || submenu, label)
|
2278
|
+
end
|
2279
|
+
|
2280
|
+
def title; @title; end
|
2281
|
+
def title=(t)
|
2282
|
+
@title = t
|
2283
|
+
Win32Gui.setwindowtexta(@hwnd, @title)
|
2284
|
+
end
|
2285
|
+
|
2286
|
+
def initialize_window
|
2287
|
+
end
|
2288
|
+
end
|
2289
|
+
|
2290
|
+
class ToolWindow < Window
|
2291
|
+
def win32styleex; Win32Gui::WS_EX_TOOLWINDOW ; end
|
2292
|
+
def win32style; Win32Gui::WS_POPUP | Win32Gui::WS_SYSMENU | Win32Gui::WS_CAPTION | Win32Gui::WS_THICKFRAME ; end
|
2293
|
+
|
2294
|
+
def initialize_visible_
|
2295
|
+
super
|
2296
|
+
# center on the parent from size in initial_size
|
2297
|
+
w, h = @widget.initial_size
|
2298
|
+
r1 = Win32Gui.alloc_c_struct('RECT')
|
2299
|
+
Win32Gui.getwindowrect(@parent.hwnd, r1)
|
2300
|
+
r2 = Win32Gui.alloc_c_struct('RECT', :left => 0, :top => 0, :right => w, :bottom => h)
|
2301
|
+
Win32Gui.adjustwindowrectex(r2, @parent.win32style, Win32Gui::FALSE, @parent.win32styleex)
|
2302
|
+
x = r1[:left]+(r1[:right]-r1[:left]-r2[:right]+r2[:left])/2
|
2303
|
+
y = r1[:top ]+(r1[:bottom]-r1[:top]-r2[:bottom]+r2[:top])/2
|
2304
|
+
Win32Gui.movewindow(@hwnd, x, y, r2[:right]-r2[:left], r2[:bottom]-r2[:top], Win32Gui::FALSE)
|
2305
|
+
end
|
2306
|
+
|
2307
|
+
def initialize(parent, *a, &b)
|
2308
|
+
@parent = parent
|
2309
|
+
super(*a, &b)
|
2310
|
+
@@mainwindow_list.delete self
|
2311
|
+
@parent.popups << self if parent
|
2312
|
+
end
|
2313
|
+
|
2314
|
+
def destroy_window
|
2315
|
+
@parent.popups.delete self if @parent
|
2316
|
+
super
|
2317
|
+
end
|
2318
|
+
end
|
2319
|
+
|
2320
|
+
class OpenFile
|
2321
|
+
def w32api(arg)
|
2322
|
+
Win32Gui.getopenfilenamea(arg)
|
2323
|
+
end
|
2324
|
+
def w32flags
|
2325
|
+
Win32Gui::OFN_PATHMUSTEXIST
|
2326
|
+
end
|
2327
|
+
|
2328
|
+
def initialize(win, title, opts={})
|
2329
|
+
buf = [0].pack('C')*512
|
2330
|
+
ofn = Win32Gui.alloc_c_struct 'OPENFILENAMEA',
|
2331
|
+
:lstructsize => :size,
|
2332
|
+
#:hwndowner => win.hwnd, # 0 for nonmodal
|
2333
|
+
:lpstrfilter => "All Files\0*.*\0\0",
|
2334
|
+
:lpstrfile => buf,
|
2335
|
+
:lpstrtitle => title,
|
2336
|
+
:nmaxfile => buf.length,
|
2337
|
+
:flags => Win32Gui::OFN_DONTADDTORECENT | Win32Gui::OFN_LONGNAMES |
|
2338
|
+
Win32Gui::OFN_HIDEREADONLY | w32flags
|
2339
|
+
ofn[:lpstrinitialdir] = opts[:path] if opts[:path]
|
2340
|
+
return if w32api(ofn) == 0
|
2341
|
+
buf = buf[0, buf.index(0.chr)] if buf.index(0.chr)
|
2342
|
+
yield buf if buf != ''
|
2343
|
+
end
|
2344
|
+
end
|
2345
|
+
|
2346
|
+
class SaveFile < OpenFile
|
2347
|
+
def w32api(arg)
|
2348
|
+
Win32Gui.getsavefilenamea(arg)
|
2349
|
+
end
|
2350
|
+
def w32flags
|
2351
|
+
Win32Gui::OFN_OVERWRITEPROMPT
|
2352
|
+
end
|
2353
|
+
end
|
2354
|
+
|
2355
|
+
class MessageBox
|
2356
|
+
def initialize(win, msg, opts={})
|
2357
|
+
opts = { :title => opts } if opts.kind_of? String
|
2358
|
+
Win32Gui.messageboxa(0, msg, opts[:title], 0)
|
2359
|
+
end
|
2360
|
+
end
|
2361
|
+
|
2362
|
+
class InputBox < ToolWindow
|
2363
|
+
class IBoxWidget < DrawableWidget
|
2364
|
+
def initialize_widget(label, opts, &b)
|
2365
|
+
@label = label
|
2366
|
+
@action = b
|
2367
|
+
@textdown = false
|
2368
|
+
@curline = opts[:text].to_s.dup
|
2369
|
+
@oldsel_x = @caret_x_select = 0
|
2370
|
+
@caret_x = @curline.length
|
2371
|
+
@caret_x_start = 0
|
2372
|
+
|
2373
|
+
add_button('Ok', :btnc1, :btnc2) { keypress(:enter) }
|
2374
|
+
add_button('Cancel', :btnc1, :btnc2) { keypress(:esc) }
|
2375
|
+
|
2376
|
+
@default_color_association = { :background => :winbg, :label => :black,
|
2377
|
+
:text => :black, :textbg => :white, :caret => :black, :btnc1 => :palegrey,
|
2378
|
+
:btnc2 => :grey, :textsel => :white, :textselbg => :darkblue }
|
2379
|
+
end
|
2380
|
+
|
2381
|
+
def resized(w, h)
|
2382
|
+
bw = 10*@font_width
|
2383
|
+
bh = @font_height*3/2
|
2384
|
+
@buttons[0].move((w-2*bw-3*@font_width)/2, 0, bw, bh)
|
2385
|
+
@buttons[1].move(@buttons[0].x + 3*@font_width + bw, 0, bw, bh)
|
2386
|
+
end
|
2387
|
+
|
2388
|
+
def initial_size
|
2389
|
+
[40*@font_width, 6*@font_height + @font_height/4]
|
2390
|
+
end
|
2391
|
+
|
2392
|
+
def paint
|
2393
|
+
y = @font_height/2
|
2394
|
+
|
2395
|
+
fixedfont = Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::ANSI_VAR_FONT))
|
2396
|
+
sz = Win32Gui.alloc_c_struct('POINT')
|
2397
|
+
Win32Gui.gettextextentpoint32a(@hdc, 'x', 1, sz)
|
2398
|
+
var_font_height = sz[:y]
|
2399
|
+
@label.each_line { |l|
|
2400
|
+
draw_string_color(:label, @font_width, y, l)
|
2401
|
+
y += var_font_height
|
2402
|
+
}
|
2403
|
+
y += @font_height
|
2404
|
+
@texty = y-1
|
2405
|
+
@texth = @font_height+1
|
2406
|
+
|
2407
|
+
Win32Gui.selectobject(@hdc, fixedfont)
|
2408
|
+
|
2409
|
+
y += @font_height*2
|
2410
|
+
@buttons.each { |b| b.y = y }
|
2411
|
+
paint_buttons
|
2412
|
+
|
2413
|
+
w_c = width/@font_width - 2
|
2414
|
+
|
2415
|
+
if @caret_x <= @caret_x_start
|
2416
|
+
@caret_x_start = [@caret_x-1, 0].max
|
2417
|
+
elsif @caret_x_start > 0 and @curline[@caret_x_start..-1].length < w_c-1
|
2418
|
+
@caret_x_start = [@curline.length-w_c+1, 0].max
|
2419
|
+
elsif @caret_x_start + w_c <= @caret_x
|
2420
|
+
@caret_x_start = [@caret_x-w_c+1, 0].max
|
2421
|
+
end
|
2422
|
+
draw_rectangle_color(:textbg, @font_width, @texty-1, @width-2*@font_width, @font_height+1)
|
2423
|
+
draw_string_color(:text, @font_width+1, @texty, @curline[@caret_x_start, w_c])
|
2424
|
+
|
2425
|
+
if @caret_x_select
|
2426
|
+
c1, c2 = [@caret_x_select, @caret_x].sort
|
2427
|
+
c1 = [[c1, @caret_x_start].max, @caret_x_start+w_c].min
|
2428
|
+
c2 = [[c2, @caret_x_start].max, @caret_x_start+w_c].min
|
2429
|
+
if c1 != c2
|
2430
|
+
draw_rectangle_color(:textselbg, @font_width+1+(c1-@caret_x_start)*@font_width, @texty-1, (c2-c1)*@font_width, @font_height+1)
|
2431
|
+
draw_string_color(:textsel, @font_width+1+(c1-@caret_x_start)*@font_width, @texty, @curline[c1...c2])
|
2432
|
+
end
|
2433
|
+
end
|
2434
|
+
|
2435
|
+
cx = [@caret_x-@caret_x_start+1, w_c].min*@font_width+1
|
2436
|
+
draw_line_color(:caret, cx, @texty, cx, @texty+@font_height-1)
|
2437
|
+
@oldcaret_x = @caret_x
|
2438
|
+
end
|
2439
|
+
|
2440
|
+
def keypress_ctrl(key)
|
2441
|
+
case key
|
2442
|
+
when ?a
|
2443
|
+
@caret_x_select = 0
|
2444
|
+
@caret_x = @curline.length
|
2445
|
+
redraw
|
2446
|
+
when ?c
|
2447
|
+
if @caret_x_select
|
2448
|
+
c1, c2 = [@caret_x, @caret_x_select].sort
|
2449
|
+
clipboard_copy @curline[c1...c2]
|
2450
|
+
end
|
2451
|
+
when ?v
|
2452
|
+
cptext = clipboard_paste.to_s
|
2453
|
+
cx = @caret_x_select || @caret_x
|
2454
|
+
@caret_x_select = nil
|
2455
|
+
c1, c2 = [cx, @caret_x].sort
|
2456
|
+
@curline[c1...c2] = cptext
|
2457
|
+
@caret_x_select = nil
|
2458
|
+
@caret_x = c1 + cptext.length
|
2459
|
+
redraw
|
2460
|
+
when ?x
|
2461
|
+
if @caret_x_select
|
2462
|
+
c1, c2 = [@caret_x, @caret_x_select].sort
|
2463
|
+
clipboard_copy @curline[c1...c2]
|
2464
|
+
@curline[c1..c2] = ''
|
2465
|
+
@caret_x_select = nil
|
2466
|
+
@caret_x = c1
|
2467
|
+
redraw
|
2468
|
+
end
|
2469
|
+
else return false
|
2470
|
+
end
|
2471
|
+
true
|
2472
|
+
end
|
2473
|
+
|
2474
|
+
def keypress(key)
|
2475
|
+
case key
|
2476
|
+
when :left
|
2477
|
+
if keyboard_state(:shift)
|
2478
|
+
@caret_x_select ||= @caret_x
|
2479
|
+
else
|
2480
|
+
@caret_x_select = nil
|
2481
|
+
end
|
2482
|
+
@caret_x -= 1 if @caret_x > 0
|
2483
|
+
update_caret
|
2484
|
+
when :right
|
2485
|
+
if keyboard_state(:shift)
|
2486
|
+
@caret_x_select ||= @caret_x
|
2487
|
+
else
|
2488
|
+
@caret_x_select = nil
|
2489
|
+
end
|
2490
|
+
@caret_x += 1 if @caret_x < @curline.length
|
2491
|
+
update_caret
|
2492
|
+
when :home
|
2493
|
+
if keyboard_state(:shift)
|
2494
|
+
@caret_x_select ||= @caret_x
|
2495
|
+
else
|
2496
|
+
@caret_x_select = nil
|
2497
|
+
end
|
2498
|
+
@caret_x = 0
|
2499
|
+
update_caret
|
2500
|
+
when :end
|
2501
|
+
if keyboard_state(:shift)
|
2502
|
+
@caret_x_select ||= @caret_x
|
2503
|
+
else
|
2504
|
+
@caret_x_select = nil
|
2505
|
+
end
|
2506
|
+
@caret_x = @curline.length
|
2507
|
+
update_caret
|
2508
|
+
when :enter
|
2509
|
+
destroy
|
2510
|
+
Gui.main_iter
|
2511
|
+
protect { @action.call(@curline.strip) }
|
2512
|
+
when :esc
|
2513
|
+
if @buttons.find { |b| b.down }
|
2514
|
+
@buttons.each { |b| b.down = false }
|
2515
|
+
redraw
|
2516
|
+
else
|
2517
|
+
destroy
|
2518
|
+
end
|
2519
|
+
when ?\x20..?\x7e
|
2520
|
+
cx = @caret_x_select || @caret_x
|
2521
|
+
@caret_x_select = nil
|
2522
|
+
c1, c2 = [cx, @caret_x].sort
|
2523
|
+
@curline[c1...c2] = key.chr
|
2524
|
+
@caret_x = c1+1
|
2525
|
+
redraw
|
2526
|
+
when :delete
|
2527
|
+
if @caret_x_select
|
2528
|
+
c1, c2 = [@caret_x, @caret_x_select].sort
|
2529
|
+
@curline[c1...c2] = ''
|
2530
|
+
@caret_x_select = nil
|
2531
|
+
@caret_x = c1
|
2532
|
+
redraw
|
2533
|
+
elsif @caret_x < @curline.length
|
2534
|
+
@curline[@caret_x, 1] = ''
|
2535
|
+
redraw
|
2536
|
+
end
|
2537
|
+
when :backspace
|
2538
|
+
if @caret_x_select
|
2539
|
+
c1, c2 = [@caret_x, @caret_x_select].sort
|
2540
|
+
@curline[c1...c2] = ''
|
2541
|
+
@caret_x_select = nil
|
2542
|
+
@caret_x = c1
|
2543
|
+
redraw
|
2544
|
+
elsif @caret_x > 0
|
2545
|
+
@caret_x -= 1
|
2546
|
+
@curline[@caret_x, 1] = ''
|
2547
|
+
redraw
|
2548
|
+
end
|
2549
|
+
else return false
|
2550
|
+
end
|
2551
|
+
true
|
2552
|
+
end
|
2553
|
+
|
2554
|
+
def click(x, y)
|
2555
|
+
if y >= @texty and y < @texty+@texth
|
2556
|
+
@caret_x_select = nil
|
2557
|
+
@caret_x = x.to_i / @font_width - 1 + @caret_x_start
|
2558
|
+
@caret_x = [[@caret_x, 0].max, @curline.length].min
|
2559
|
+
@textdown = @caret_x
|
2560
|
+
update_caret
|
2561
|
+
elsif click_buttons(x, y)
|
2562
|
+
redraw
|
2563
|
+
end
|
2564
|
+
end
|
2565
|
+
|
2566
|
+
def mousemove(x, y)
|
2567
|
+
if @textdown
|
2568
|
+
x = x.to_i / @font_width - 1 + @caret_x_start
|
2569
|
+
x = [[x, 0].max, @curline.length].min
|
2570
|
+
if x != @textdown
|
2571
|
+
@caret_x_select = @textdown
|
2572
|
+
@caret_x = x
|
2573
|
+
redraw
|
2574
|
+
end
|
2575
|
+
end
|
2576
|
+
end
|
2577
|
+
|
2578
|
+
def mouserelease(x, y)
|
2579
|
+
if @textdown
|
2580
|
+
x = x.to_i / @font_width - 1 + @caret_x_start
|
2581
|
+
x = [[x, 0].max, @curline.length].min
|
2582
|
+
if x != @textdown
|
2583
|
+
@caret_x_select = @textdown
|
2584
|
+
@caret_x = x
|
2585
|
+
redraw
|
2586
|
+
end
|
2587
|
+
@textdown = false
|
2588
|
+
elsif mouserelease_buttons(x, y)
|
2589
|
+
end
|
2590
|
+
end
|
2591
|
+
|
2592
|
+
def update_caret
|
2593
|
+
return if @oldcaret_x == @caret_x and @oldsel_x == @caret_x_select
|
2594
|
+
redraw
|
2595
|
+
@oldsel_x = @caret_x_select
|
2596
|
+
@oldcaret_x = @caret_x
|
2597
|
+
end
|
2598
|
+
|
2599
|
+
def destroy
|
2600
|
+
@parent.destroy
|
2601
|
+
end
|
2602
|
+
|
2603
|
+
def text
|
2604
|
+
@curline
|
2605
|
+
end
|
2606
|
+
def text=(t)
|
2607
|
+
@curline = t
|
2608
|
+
@caret_x_select = 0
|
2609
|
+
@caret_x = t.length
|
2610
|
+
redraw
|
2611
|
+
end
|
2612
|
+
|
2613
|
+
def dragdropfile(f)
|
2614
|
+
cx = @caret_x_select || @caret_x
|
2615
|
+
@caret_x_select = nil
|
2616
|
+
c1, c2 = [cx, @caret_x].sort
|
2617
|
+
@curline[c1...c2] = f
|
2618
|
+
@caret_x_select = nil
|
2619
|
+
@caret_x = c1 + f.length
|
2620
|
+
redraw
|
2621
|
+
end
|
2622
|
+
end
|
2623
|
+
def initialize_window(prompt, opts={}, &b)
|
2624
|
+
self.title = opts[:title] ? opts[:title] : 'input'
|
2625
|
+
self.widget = IBoxWidget.new(prompt, opts, &b)
|
2626
|
+
end
|
2627
|
+
|
2628
|
+
def text ; @widget.text ; end
|
2629
|
+
def text=(t) ; @widget.text = t ; end
|
2630
|
+
end
|
2631
|
+
|
2632
|
+
class ListWindow < ToolWindow
|
2633
|
+
class LBoxWidget < DrawableWidget
|
2634
|
+
def initialize_widget(list, opts={}, &b)
|
2635
|
+
ccnt = list.first.length
|
2636
|
+
# store a true/false per column saying if the original data was integers (for col sorting)
|
2637
|
+
@list_ints = list[1..-1].transpose.map { |col| col.all? { |e| e.kind_of? Integer } } rescue []
|
2638
|
+
@list = list.map { |l|
|
2639
|
+
l += ['']*(ccnt - l.length) if l.length < ccnt
|
2640
|
+
l = l[0, ccnt] if l.length > ccnt
|
2641
|
+
l.map { |w| w.to_s }
|
2642
|
+
}
|
2643
|
+
# length of the longest element of the column
|
2644
|
+
@colwmax = @list.transpose.map { |l| l.map { |w| w.length }.max }
|
2645
|
+
@titles = @list.shift
|
2646
|
+
|
2647
|
+
@action = b
|
2648
|
+
@linehead = 0
|
2649
|
+
@color_callback = opts[:color_callback] # lambda { |ary_entries_text| [color_font, color_bg] }
|
2650
|
+
@noclose_dblclick = opts[:noclose_dblclick]
|
2651
|
+
# index of the currently selected row
|
2652
|
+
@linesel = nil
|
2653
|
+
# ary indicating whether a title label is being clicked
|
2654
|
+
@btndown = []
|
2655
|
+
@btnheight = @font_height * 4/3
|
2656
|
+
@sbh = 0 # position of the hz scrollbar
|
2657
|
+
@sbv = 0
|
2658
|
+
|
2659
|
+
@default_color_association = { :background => :winbg, :label => :black,
|
2660
|
+
:text => :black, :textbg => :white, :btnc1 => :white, :btnc2 => :grey,
|
2661
|
+
:textsel => :white, :textselbg => :darkblue }
|
2662
|
+
end
|
2663
|
+
|
2664
|
+
def initial_size
|
2665
|
+
@colw = @colwmax.map { |w| (w+1) * @font_width }
|
2666
|
+
allw = @colw.inject(0) { |a, i| a+i }
|
2667
|
+
[[allw, 80*@font_width].min, [@list.length+1, 30].min * @font_height+2]
|
2668
|
+
end
|
2669
|
+
|
2670
|
+
def resized(w, h)
|
2671
|
+
# scrollbar stuff
|
2672
|
+
fullw = @colwmax.inject(0) { |a, i| a+i+1 } * @font_width
|
2673
|
+
@sbh = fullw-w if @sbh > fullw-w
|
2674
|
+
@sbh = 0 if @sbh < 0
|
2675
|
+
sif = Win32Gui.alloc_c_struct('SCROLLINFO',
|
2676
|
+
:cbsize => :size, :fmask => Win32Gui::SIF_ALL,
|
2677
|
+
:nmin => 0, :nmax => fullw-1, :npage => w, :npos => @sbh)
|
2678
|
+
Win32Gui.setscrollinfo(@hwnd, Win32Gui::SB_HORZ, sif, Win32Gui::TRUE)
|
2679
|
+
|
2680
|
+
fullh = @list.length * @font_height + @btnheight
|
2681
|
+
@sbv = fullh-h if @sbv > fullh-h
|
2682
|
+
@sbv = 0 if @sbv < 0
|
2683
|
+
sif = Win32Gui.alloc_c_struct('SCROLLINFO',
|
2684
|
+
:cbsize => :size, :fmask => Win32Gui::SIF_ALL,
|
2685
|
+
:nmin => 0, :nmax => fullh-1, :npage => h, :npos => @sbv)
|
2686
|
+
Win32Gui.setscrollinfo(@hwnd, Win32Gui::SB_VERT, sif, Win32Gui::TRUE)
|
2687
|
+
|
2688
|
+
# resize columns to fill available hz space
|
2689
|
+
if w > fullw
|
2690
|
+
mi = (w-fullw) / @colw.length
|
2691
|
+
mm = (w-fullw) % @colw.length
|
2692
|
+
@colw.length.times { |i|
|
2693
|
+
@colw[i] = (@colwmax[i]+1)*@font_width + mi + (i < mm ? 1 : 0)
|
2694
|
+
}
|
2695
|
+
redraw
|
2696
|
+
end
|
2697
|
+
end
|
2698
|
+
|
2699
|
+
def paint
|
2700
|
+
@btnx = []
|
2701
|
+
@btny = 0
|
2702
|
+
@btnheight = @font_height * 4/3
|
2703
|
+
x = 0
|
2704
|
+
@colw.each { |w|
|
2705
|
+
@btnx << x
|
2706
|
+
x += w
|
2707
|
+
}
|
2708
|
+
|
2709
|
+
x -= @sbh
|
2710
|
+
y = @btnheight
|
2711
|
+
@linehead = @sbv / @font_height
|
2712
|
+
y -= @sbv % @font_height
|
2713
|
+
tl = (@linesel || -1) - @linehead
|
2714
|
+
@lineshown = @list[@linehead, (height-y)/@font_height+1].to_a.length
|
2715
|
+
@list[@linehead, @lineshown].to_a.each { |l|
|
2716
|
+
x = @btnx.first - @sbh
|
2717
|
+
ct, cb = @color_callback[l] if @color_callback
|
2718
|
+
ct ||= :text
|
2719
|
+
cb ||= :textbg
|
2720
|
+
ct, cb = :textsel, :textselbg if tl == 0
|
2721
|
+
tl -= 1
|
2722
|
+
draw_rectangle_color(cb, x, y, width-2*x, @font_height)
|
2723
|
+
l.zip(@colw).each { |t, w|
|
2724
|
+
draw_string_color(ct, x+@font_width/2, y, t[0, w/@font_width-1])
|
2725
|
+
x += w
|
2726
|
+
}
|
2727
|
+
y += @font_height
|
2728
|
+
}
|
2729
|
+
|
2730
|
+
@titles.zip(@colw, @btnx, @btndown).each { |t, w, bx, d|
|
2731
|
+
x = bx - @sbh
|
2732
|
+
y = @btny
|
2733
|
+
h = @btnheight-1
|
2734
|
+
c1 = d ? :btnc2 : :btnc1
|
2735
|
+
c2 = d ? :btnc1 : :btnc2
|
2736
|
+
draw_rectangle_color(:background, x, y, w-1, h)
|
2737
|
+
draw_line_color(c1, x, y, x, y+h)
|
2738
|
+
draw_line_color(c1, x, y, x+w-1, y)
|
2739
|
+
draw_line_color(c2, x+w-1, y+h, x, y+h)
|
2740
|
+
draw_line_color(c2, x+w-1, y+h, x+w-1, y)
|
2741
|
+
|
2742
|
+
cw = w/@font_width-1
|
2743
|
+
xo = [(cw-t.length) * @font_width/2, 0].max # center titles
|
2744
|
+
draw_string_color(:label, x+@font_width/2+xo, y+@font_height/6, t[0, cw])
|
2745
|
+
}
|
2746
|
+
end
|
2747
|
+
|
2748
|
+
def keypress(key)
|
2749
|
+
case key
|
2750
|
+
when :up
|
2751
|
+
if not @linesel
|
2752
|
+
@linesel = @linehead
|
2753
|
+
elsif @linesel > 0
|
2754
|
+
@linesel -= 1
|
2755
|
+
vscroll(@linesel*@font_height) if @linesel < @linehead
|
2756
|
+
end
|
2757
|
+
redraw
|
2758
|
+
when :down
|
2759
|
+
if not @linesel
|
2760
|
+
@linesel = @linehead
|
2761
|
+
elsif @linesel < @list.length-1
|
2762
|
+
@linesel += 1
|
2763
|
+
vscroll((@linesel-(@lineshown-1))*@font_height) if @linehead < @linesel-(@lineshown-1)
|
2764
|
+
end
|
2765
|
+
redraw
|
2766
|
+
when :pgup
|
2767
|
+
off = [@lineshown, [@lineshown/2, 5].max].min
|
2768
|
+
if not @linesel
|
2769
|
+
@linesel = @linehead
|
2770
|
+
elsif @linesel != @linehead
|
2771
|
+
@linesel = [@linehead, @linesel-off].max
|
2772
|
+
else
|
2773
|
+
@linesel = [0, @linehead-off].max
|
2774
|
+
vscroll(@linesel*@font_height)
|
2775
|
+
end
|
2776
|
+
redraw
|
2777
|
+
when :pgdown
|
2778
|
+
n = @lineshown-1
|
2779
|
+
off = [@lineshown, [@lineshown/2, 5].max].min
|
2780
|
+
if not @linesel
|
2781
|
+
@linesel = @linehead+n
|
2782
|
+
elsif @linesel != @linehead+n
|
2783
|
+
@linesel = [@linehead+n, @linesel+off].min
|
2784
|
+
else
|
2785
|
+
vscroll((@linehead+off)*@font_height)
|
2786
|
+
@linesel = [@linehead+n, @list.length-1].min
|
2787
|
+
end
|
2788
|
+
redraw
|
2789
|
+
when :home
|
2790
|
+
@linesel = 0
|
2791
|
+
vscroll(0)
|
2792
|
+
redraw
|
2793
|
+
when :end
|
2794
|
+
@linesel = @list.length-1
|
2795
|
+
vscroll(@list.length*@font_height)
|
2796
|
+
redraw
|
2797
|
+
when :enter
|
2798
|
+
if @linesel and @list[@linesel]
|
2799
|
+
protect { @action.call(@list[@linesel]) }
|
2800
|
+
end
|
2801
|
+
when :esc
|
2802
|
+
if not @btndown.compact.empty?
|
2803
|
+
@btndown = []
|
2804
|
+
redraw
|
2805
|
+
else
|
2806
|
+
destroy
|
2807
|
+
end
|
2808
|
+
else return false
|
2809
|
+
end
|
2810
|
+
true
|
2811
|
+
end
|
2812
|
+
|
2813
|
+
def mouse_wheel(dir, x, y)
|
2814
|
+
case dir
|
2815
|
+
when :up
|
2816
|
+
off = [@lineshown, [@lineshown/2, 5].max].min
|
2817
|
+
vscroll((@linehead-off)*@font_height)
|
2818
|
+
redraw
|
2819
|
+
when :down
|
2820
|
+
n = @lineshown-1
|
2821
|
+
off = [@lineshown, [@lineshown/2, 5].max].min
|
2822
|
+
vscroll((@linehead+off)*@font_height)
|
2823
|
+
redraw
|
2824
|
+
end
|
2825
|
+
end
|
2826
|
+
|
2827
|
+
def hscroll(val)
|
2828
|
+
Win32Gui.setscrollpos(@hwnd, Win32Gui::SB_HORZ, val, Win32Gui::TRUE)
|
2829
|
+
@sbh = Win32Gui.getscrollpos(@hwnd, Win32Gui::SB_HORZ) # clipping, etc
|
2830
|
+
redraw
|
2831
|
+
end
|
2832
|
+
|
2833
|
+
def vscroll(val)
|
2834
|
+
Win32Gui.setscrollpos(@hwnd, Win32Gui::SB_VERT, val, Win32Gui::TRUE)
|
2835
|
+
@sbv = Win32Gui.getscrollpos(@hwnd, Win32Gui::SB_VERT)
|
2836
|
+
redraw
|
2837
|
+
end
|
2838
|
+
|
2839
|
+
def xtobtn(x)
|
2840
|
+
x += @sbh
|
2841
|
+
if x < @btnx.first
|
2842
|
+
return 0
|
2843
|
+
elsif x >= @btnx.last + @colw.last
|
2844
|
+
return @btnx.length-1
|
2845
|
+
else
|
2846
|
+
@btnx.zip(@colw).each_with_index { |(bx, bw), i|
|
2847
|
+
return i if x >= bx and x < bx+bw
|
2848
|
+
}
|
2849
|
+
end
|
2850
|
+
end
|
2851
|
+
|
2852
|
+
def click(x, y)
|
2853
|
+
if y >= @btny and y < @btny+@btnheight
|
2854
|
+
# TODO column resize
|
2855
|
+
@btndown[xtobtn(x)] = true
|
2856
|
+
redraw
|
2857
|
+
elsif y >= @btny+@btnheight
|
2858
|
+
y += @sbv % @font_height
|
2859
|
+
cy = @linehead + (y - @btny - @btnheight)/@font_height
|
2860
|
+
if cy < @list.length
|
2861
|
+
@linesel = cy
|
2862
|
+
redraw
|
2863
|
+
Gui.main_iter
|
2864
|
+
protect { @action.call(@list[@linesel]) }
|
2865
|
+
end
|
2866
|
+
end
|
2867
|
+
end
|
2868
|
+
|
2869
|
+
def doubleclick(x, y)
|
2870
|
+
if y >= @btny+@btnheight
|
2871
|
+
return click(x, y) if @noclose_dblclick
|
2872
|
+
y += @sbv % @font_height
|
2873
|
+
cy = @linehead + (y - @btny - @btnheight)/@font_height
|
2874
|
+
if cy < @list.length
|
2875
|
+
destroy
|
2876
|
+
Gui.main_iter
|
2877
|
+
protect { @action.call(@list[@linesel]) }
|
2878
|
+
end
|
2879
|
+
end
|
2880
|
+
end
|
2881
|
+
|
2882
|
+
def mousemove(x, y)
|
2883
|
+
if @btndown.compact.first
|
2884
|
+
@btndown = []
|
2885
|
+
@btndown[xtobtn(x)] = true
|
2886
|
+
redraw
|
2887
|
+
end
|
2888
|
+
end
|
2889
|
+
|
2890
|
+
def mouserelease(x, y)
|
2891
|
+
if @btndown.compact.first
|
2892
|
+
@btndown = []
|
2893
|
+
col = xtobtn(x)
|
2894
|
+
cursel = @list[@linesel] if @linesel
|
2895
|
+
if @list_ints[col]
|
2896
|
+
nlist = @list.sort_by { |a| [a[col].to_i, a] }
|
2897
|
+
else
|
2898
|
+
nlist = @list.sort_by { |a| [a[col], a] }
|
2899
|
+
end
|
2900
|
+
nlist.reverse! if nlist == @list
|
2901
|
+
@list = nlist
|
2902
|
+
@linehead = 0
|
2903
|
+
if cursel
|
2904
|
+
@linesel = @list.index(cursel)
|
2905
|
+
@linehead = @linesel - (@lineshown-1) if @linehead < @linesel-(@lineshown-1)
|
2906
|
+
end
|
2907
|
+
redraw
|
2908
|
+
end
|
2909
|
+
end
|
2910
|
+
|
2911
|
+
def destroy
|
2912
|
+
@parent.destroy
|
2913
|
+
end
|
2914
|
+
end
|
2915
|
+
def initialize_window(title, list, opts={}, &b)
|
2916
|
+
@ondestroy = opts[:ondestroy]
|
2917
|
+
self.title = title
|
2918
|
+
self.widget = LBoxWidget.new(list, opts, &b)
|
2919
|
+
end
|
2920
|
+
|
2921
|
+
def destroy_window
|
2922
|
+
@ondestroy.call if @ondestroy
|
2923
|
+
super()
|
2924
|
+
end
|
2925
|
+
|
2926
|
+
def windowproc(hwnd, msg, wparam, lparam)
|
2927
|
+
case msg
|
2928
|
+
when Win32Gui::WM_HSCROLL
|
2929
|
+
sif = Win32Gui.alloc_c_struct('SCROLLINFO', :cbsize => :size, :fmask => Win32Gui::SIF_ALL)
|
2930
|
+
Win32Gui.getscrollinfo(@hwnd, Win32Gui::SB_HORZ, sif)
|
2931
|
+
case wparam & 0xffff
|
2932
|
+
when Win32Gui::SB_THUMBPOSITION; val = sif.ntrackpos
|
2933
|
+
when Win32Gui::SB_THUMBTRACK; val = sif.ntrackpos
|
2934
|
+
when Win32Gui::SB_LINELEFT; val = sif.npos - 1
|
2935
|
+
when Win32Gui::SB_LINERIGHT; val = sif.npos + 1
|
2936
|
+
when Win32Gui::SB_PAGELEFT; val = sif.npos - sif.npage
|
2937
|
+
when Win32Gui::SB_PAGERIGHT; val = sif.npos + sif.npage
|
2938
|
+
else return 0
|
2939
|
+
end
|
2940
|
+
@widget.hscroll val
|
2941
|
+
when Win32Gui::WM_VSCROLL
|
2942
|
+
sif = Win32Gui.alloc_c_struct('SCROLLINFO', :cbsize => :size, :fmask => Win32Gui::SIF_ALL)
|
2943
|
+
Win32Gui.getscrollinfo(@hwnd, Win32Gui::SB_VERT, sif)
|
2944
|
+
case wparam & 0xffff
|
2945
|
+
when Win32Gui::SB_THUMBPOSITION; val = sif.ntrackpos
|
2946
|
+
when Win32Gui::SB_THUMBTRACK; val = sif.ntrackpos; nopos = true
|
2947
|
+
when Win32Gui::SB_LINEDOWN; val = sif.npos + 1
|
2948
|
+
when Win32Gui::SB_LINEUP; val = sif.npos - 1
|
2949
|
+
when Win32Gui::SB_PAGEDOWN; val = sif.npos + sif.npage
|
2950
|
+
when Win32Gui::SB_PAGEUP; val = sif.npos - sif.npage
|
2951
|
+
else return 0
|
2952
|
+
end
|
2953
|
+
@widget.vscroll val
|
2954
|
+
else return super(hwnd, msg, wparam, lparam)
|
2955
|
+
end
|
2956
|
+
0
|
2957
|
+
end
|
2958
|
+
end
|
2959
|
+
|
2960
|
+
def Gui.main
|
2961
|
+
@idle_procs ||= []
|
2962
|
+
msg = Win32Gui.alloc_c_struct('MSG')
|
2963
|
+
loop do
|
2964
|
+
if Win32Gui.peekmessagea(msg, 0, 0, 0, Win32Gui::PM_NOREMOVE) != 0 or
|
2965
|
+
Win32Gui.msgwaitformultipleobjects(0, 0, Win32Gui::FALSE, 500,
|
2966
|
+
Win32Gui::QS_ALLINPUT) != Win32Gui::WAIT_TIMEOUT
|
2967
|
+
ret = Win32Gui.getmessagea(msg, 0, 0, 0)
|
2968
|
+
break if ret == 0
|
2969
|
+
raise Win32Gui.last_error_msg if ret < 0
|
2970
|
+
Win32Gui.translatemessage(msg)
|
2971
|
+
Win32Gui.dispatchmessagea(msg)
|
2972
|
+
end
|
2973
|
+
while not @idle_procs.empty? and Win32Gui.peekmessagea(msg, 0, 0, 0, Win32Gui::PM_NOREMOVE) == 0
|
2974
|
+
@idle_procs.delete_if { |ip| not ip.call }
|
2975
|
+
end
|
2976
|
+
end
|
2977
|
+
msg[:wparam]
|
2978
|
+
end
|
2979
|
+
|
2980
|
+
def Gui.main_quit
|
2981
|
+
Win32Gui.postquitmessage(0)
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
def Gui.main_iter
|
2985
|
+
msg = Win32Gui.alloc_c_struct('MSG')
|
2986
|
+
while Win32Gui.peekmessagea(msg, 0, 0, 0, Win32Gui::PM_REMOVE) != 0
|
2987
|
+
Win32Gui.translatemessage(msg)
|
2988
|
+
Win32Gui.dispatchmessagea(msg)
|
2989
|
+
end
|
2990
|
+
end
|
2991
|
+
|
2992
|
+
# add a lambda to be run whenever the messageloop is idle
|
2993
|
+
# the lambda is removed if it returns nil/false
|
2994
|
+
def Gui.idle_add(&b)
|
2995
|
+
@idle_procs ||= []
|
2996
|
+
@idle_procs << b
|
2997
|
+
end
|
2998
|
+
|
2999
|
+
end
|
3000
|
+
end
|
3001
|
+
|
3002
|
+
require 'metasm/gui/dasm_main'
|
3003
|
+
require 'metasm/gui/debug'
|
3004
|
+
|