wrb 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README +28 -0
- data/Rakefile +66 -0
- data/bin/wrb +41 -0
- data/bin/wrb.bat +6 -0
- data/ext/rwin/aatree.c +192 -0
- data/ext/rwin/aatree.h +55 -0
- data/ext/rwin/extconf.rb +47 -0
- data/ext/rwin/rw_api.c +2058 -0
- data/ext/rwin/rw_devices.c +215 -0
- data/ext/rwin/rw_gdiplus.h +278 -0
- data/ext/rwin/rw_graphics.c +1583 -0
- data/ext/rwin/rw_resources.c +1988 -0
- data/ext/rwin/rw_ubfuncs.c +281 -0
- data/ext/rwin/rw_windows.c +1936 -0
- data/ext/rwin/rwin.c +451 -0
- data/ext/rwin/rwin.h +442 -0
- data/lib/rwin.rb +820 -0
- data/lib/wrb.rb +20 -0
- data/lib/wrb/applications/frmdesigner/angle.cur +0 -0
- data/lib/wrb/applications/frmdesigner/angle2.cur +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Button.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Button.rb +34 -0
- data/lib/wrb/applications/frmdesigner/controls/Checkbox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Checkbox.rb +10 -0
- data/lib/wrb/applications/frmdesigner/controls/Combobox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Combobox.rb +88 -0
- data/lib/wrb/applications/frmdesigner/controls/ComboboxEx.rb +97 -0
- data/lib/wrb/applications/frmdesigner/controls/Comboboxex.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.rb +11 -0
- data/lib/wrb/applications/frmdesigner/controls/Edit.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Edit.rb +8 -0
- data/lib/wrb/applications/frmdesigner/controls/Groupbox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Groupbox.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Imagelist.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Imagelist.rb +115 -0
- data/lib/wrb/applications/frmdesigner/controls/Listbox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Listbox.rb +77 -0
- data/lib/wrb/applications/frmdesigner/controls/Listview.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Listview.rb +157 -0
- data/lib/wrb/applications/frmdesigner/controls/Menu.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Menu.rb +198 -0
- data/lib/wrb/applications/frmdesigner/controls/Menubar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Menubar.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/MonthCalender.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Monthcalender.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Panel.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Panel.rb +30 -0
- data/lib/wrb/applications/frmdesigner/controls/Progressbar.rb +10 -0
- data/lib/wrb/applications/frmdesigner/controls/Radiobutton.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Radiobutton.rb +13 -0
- data/lib/wrb/applications/frmdesigner/controls/Rebar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Rebar.rb +162 -0
- data/lib/wrb/applications/frmdesigner/controls/Splitter.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Splitter.rb +66 -0
- data/lib/wrb/applications/frmdesigner/controls/Static.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Static.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Statusbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Statusbar.rb +103 -0
- data/lib/wrb/applications/frmdesigner/controls/Tabctrl.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Tabctrl.rb +136 -0
- data/lib/wrb/applications/frmdesigner/controls/Timer.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Timer.rb +36 -0
- data/lib/wrb/applications/frmdesigner/controls/Toolbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Toolbar.rb +165 -0
- data/lib/wrb/applications/frmdesigner/controls/Trackbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Trackbar.rb +34 -0
- data/lib/wrb/applications/frmdesigner/controls/Treeview.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Treeview.rb +107 -0
- data/lib/wrb/applications/frmdesigner/controls/Updown.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Updown.rb +31 -0
- data/lib/wrb/applications/frmdesigner/controls/default.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/progressbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/unselect.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/fddialogs.rb +87 -0
- data/lib/wrb/applications/frmdesigner/fdesign.rb +1315 -0
- data/lib/wrb/applications/frmdesigner/fdmodules.rb +1394 -0
- data/lib/wrb/applications/frmdesigner/fdparseform.rb +197 -0
- data/lib/wrb/applications/frmdesigner/img13.bmp +0 -0
- data/lib/wrb/base.rb +1294 -0
- data/lib/wrb/combocommon.rb +77 -0
- data/lib/wrb/commctrlconst.rb +139 -0
- data/lib/wrb/commdlg.rb +77 -0
- data/lib/wrb/components/animate.rb +114 -0
- data/lib/wrb/components/bitmap.rb +116 -0
- data/lib/wrb/components/button.rb +134 -0
- data/lib/wrb/components/canvas.rb +266 -0
- data/lib/wrb/components/checkbox.rb +118 -0
- data/lib/wrb/components/choosecolordlg.rb +87 -0
- data/lib/wrb/components/choosefontdlg.rb +142 -0
- data/lib/wrb/components/clipboard.rb +174 -0
- data/lib/wrb/components/combobox.rb +282 -0
- data/lib/wrb/components/comboboxex.rb +574 -0
- data/lib/wrb/components/cursor.rb +91 -0
- data/lib/wrb/components/datetimepicker.rb +197 -0
- data/lib/wrb/components/ddeclient.rb +180 -0
- data/lib/wrb/components/ddeserver.rb +131 -0
- data/lib/wrb/components/dialog.rb +228 -0
- data/lib/wrb/components/edit.rb +412 -0
- data/lib/wrb/components/font.rb +35 -0
- data/lib/wrb/components/form.rb +65 -0
- data/lib/wrb/components/groupbox.rb +122 -0
- data/lib/wrb/components/header.rb +479 -0
- data/lib/wrb/components/hotkeyctrl.rb +72 -0
- data/lib/wrb/components/icon.rb +109 -0
- data/lib/wrb/components/imagelist.rb +396 -0
- data/lib/wrb/components/inifile.rb +97 -0
- data/lib/wrb/components/listbox.rb +149 -0
- data/lib/wrb/components/listview.rb +1467 -0
- data/lib/wrb/components/menu.rb +592 -0
- data/lib/wrb/components/menubar.rb +84 -0
- data/lib/wrb/components/monthcalender.rb +164 -0
- data/lib/wrb/components/openfilenamedlg.rb +147 -0
- data/lib/wrb/components/pager.rb +199 -0
- data/lib/wrb/components/panel.rb +103 -0
- data/lib/wrb/components/picture.rb +55 -0
- data/lib/wrb/components/printdlg.rb +148 -0
- data/lib/wrb/components/printdlgex.rb +117 -0
- data/lib/wrb/components/printer.rb +97 -0
- data/lib/wrb/components/progressbar.rb +140 -0
- data/lib/wrb/components/radiobutton.rb +49 -0
- data/lib/wrb/components/rebar.rb +830 -0
- data/lib/wrb/components/registry.rb +408 -0
- data/lib/wrb/components/richedit.rb +1181 -0
- data/lib/wrb/components/savefilenamedlg.rb +27 -0
- data/lib/wrb/components/scintilla.rb +1298 -0
- data/lib/wrb/components/scrollbar.rb +239 -0
- data/lib/wrb/components/splitter.rb +494 -0
- data/lib/wrb/components/static.rb +198 -0
- data/lib/wrb/components/statusbar.rb +490 -0
- data/lib/wrb/components/tabctrl.rb +686 -0
- data/lib/wrb/components/timer.rb +117 -0
- data/lib/wrb/components/toolbar.rb +1107 -0
- data/lib/wrb/components/tooltip.rb +651 -0
- data/lib/wrb/components/trackbar.rb +298 -0
- data/lib/wrb/components/treeview.rb +845 -0
- data/lib/wrb/components/updown.rb +198 -0
- data/lib/wrb/ddeml.rb +241 -0
- data/lib/wrb/documents/animate.html +46 -0
- data/lib/wrb/documents/bitmap.html +69 -0
- data/lib/wrb/documents/button.html +78 -0
- data/lib/wrb/documents/canvas.html +137 -0
- data/lib/wrb/documents/checkbox.html +77 -0
- data/lib/wrb/documents/choosecolordlg.html +29 -0
- data/lib/wrb/documents/choosefontdlg.html +31 -0
- data/lib/wrb/documents/clipboard.html +31 -0
- data/lib/wrb/documents/combobox.html +117 -0
- data/lib/wrb/documents/comboboxex.html +139 -0
- data/lib/wrb/documents/control.html +53 -0
- data/lib/wrb/documents/cursor.html +45 -0
- data/lib/wrb/documents/datetimepicker.html +70 -0
- data/lib/wrb/documents/ddeclient.html +33 -0
- data/lib/wrb/documents/ddeserver.html +26 -0
- data/lib/wrb/documents/dialog.html +78 -0
- data/lib/wrb/documents/edit.html +169 -0
- data/lib/wrb/documents/empty.html +11 -0
- data/lib/wrb/documents/favicon.png +0 -0
- data/lib/wrb/documents/font.html +38 -0
- data/lib/wrb/documents/form.html +63 -0
- data/lib/wrb/documents/groupbox.html +57 -0
- data/lib/wrb/documents/header.html +85 -0
- data/lib/wrb/documents/hotkeyctrl.html +42 -0
- data/lib/wrb/documents/icon.html +45 -0
- data/lib/wrb/documents/imagelist.html +101 -0
- data/lib/wrb/documents/images/button.png +0 -0
- data/lib/wrb/documents/images/checkbox.png +0 -0
- data/lib/wrb/documents/images/combobox.png +0 -0
- data/lib/wrb/documents/images/comboboxex.png +0 -0
- data/lib/wrb/documents/images/datetimepicker.png +0 -0
- data/lib/wrb/documents/images/edit.png +0 -0
- data/lib/wrb/documents/images/groupbox.png +0 -0
- data/lib/wrb/documents/images/hotkeyctrl.png +0 -0
- data/lib/wrb/documents/images/listbox.png +0 -0
- data/lib/wrb/documents/images/listview.png +0 -0
- data/lib/wrb/documents/images/menu.png +0 -0
- data/lib/wrb/documents/images/menubar.png +0 -0
- data/lib/wrb/documents/images/monthcalender.png +0 -0
- data/lib/wrb/documents/images/progressbar.png +0 -0
- data/lib/wrb/documents/images/radiobutton.png +0 -0
- data/lib/wrb/documents/images/rebar.png +0 -0
- data/lib/wrb/documents/images/richedit.png +0 -0
- data/lib/wrb/documents/images/splitter.png +0 -0
- data/lib/wrb/documents/images/static.png +0 -0
- data/lib/wrb/documents/images/statusbar.png +0 -0
- data/lib/wrb/documents/images/tabctrl.png +0 -0
- data/lib/wrb/documents/images/toolbar.png +0 -0
- data/lib/wrb/documents/images/tooltip.png +0 -0
- data/lib/wrb/documents/images/trackbar.png +0 -0
- data/lib/wrb/documents/images/treeview.png +0 -0
- data/lib/wrb/documents/images/updown.png +0 -0
- data/lib/wrb/documents/index.html +155 -0
- data/lib/wrb/documents/inifile.html +36 -0
- data/lib/wrb/documents/license.txt +22 -0
- data/lib/wrb/documents/listbox.html +96 -0
- data/lib/wrb/documents/listview.html +277 -0
- data/lib/wrb/documents/make_doc.rb +596 -0
- data/lib/wrb/documents/menu.html +144 -0
- data/lib/wrb/documents/menubar.html +54 -0
- data/lib/wrb/documents/monthcalender.html +48 -0
- data/lib/wrb/documents/openfilenamedlg.html +36 -0
- data/lib/wrb/documents/pager.html +63 -0
- data/lib/wrb/documents/panel.html +32 -0
- data/lib/wrb/documents/picture.html +48 -0
- data/lib/wrb/documents/printdlg.html +35 -0
- data/lib/wrb/documents/printdlgex.html +35 -0
- data/lib/wrb/documents/printer.html +40 -0
- data/lib/wrb/documents/progressbar.html +69 -0
- data/lib/wrb/documents/radiobutton.html +51 -0
- data/lib/wrb/documents/rebar.html +143 -0
- data/lib/wrb/documents/registry.html +36 -0
- data/lib/wrb/documents/richedit.html +232 -0
- data/lib/wrb/documents/samples/editimg.bmp +0 -0
- data/lib/wrb/documents/samples/editimg.iml +0 -0
- data/lib/wrb/documents/samples/fileimg.bmp +0 -0
- data/lib/wrb/documents/samples/fileimg.iml +0 -0
- data/lib/wrb/documents/samples/sample_button.rb +21 -0
- data/lib/wrb/documents/samples/sample_checkbox.rb +18 -0
- data/lib/wrb/documents/samples/sample_combobox.rb +18 -0
- data/lib/wrb/documents/samples/sample_comboboxex.rb +23 -0
- data/lib/wrb/documents/samples/sample_datetimepicker.rb +11 -0
- data/lib/wrb/documents/samples/sample_edit.rb +25 -0
- data/lib/wrb/documents/samples/sample_groupbox.rb +19 -0
- data/lib/wrb/documents/samples/sample_hotkeyctrl.rb +12 -0
- data/lib/wrb/documents/samples/sample_listbox.rb +12 -0
- data/lib/wrb/documents/samples/sample_listview.rb +32 -0
- data/lib/wrb/documents/samples/sample_menu.rb +21 -0
- data/lib/wrb/documents/samples/sample_menubar.rb +23 -0
- data/lib/wrb/documents/samples/sample_monthcalender.rb +11 -0
- data/lib/wrb/documents/samples/sample_progressbar.rb +14 -0
- data/lib/wrb/documents/samples/sample_radiobutton.rb +14 -0
- data/lib/wrb/documents/samples/sample_rebar.rb +25 -0
- data/lib/wrb/documents/samples/sample_richedit.rb +60 -0
- data/lib/wrb/documents/samples/sample_splitter.rb +33 -0
- data/lib/wrb/documents/samples/sample_static.rb +15 -0
- data/lib/wrb/documents/samples/sample_statusbar.rb +17 -0
- data/lib/wrb/documents/samples/sample_tabctrl.rb +19 -0
- data/lib/wrb/documents/samples/sample_toolbar.rb +29 -0
- data/lib/wrb/documents/samples/sample_tooltip.rb +50 -0
- data/lib/wrb/documents/samples/sample_trackbar.rb +30 -0
- data/lib/wrb/documents/samples/sample_treeview.rb +19 -0
- data/lib/wrb/documents/samples/sample_updown.rb +18 -0
- data/lib/wrb/documents/samples/sampleimg16.iml +0 -0
- data/lib/wrb/documents/samples/sampleimg32.iml +0 -0
- data/lib/wrb/documents/samples/samplemg16.png +0 -0
- data/lib/wrb/documents/samples/samplemg32.png +0 -0
- data/lib/wrb/documents/samples/wrb.ico +0 -0
- data/lib/wrb/documents/savefilenamedlg.html +19 -0
- data/lib/wrb/documents/scrollbar.html +60 -0
- data/lib/wrb/documents/splitter.html +96 -0
- data/lib/wrb/documents/static.html +84 -0
- data/lib/wrb/documents/statusbar.html +110 -0
- data/lib/wrb/documents/tabctrl.html +151 -0
- data/lib/wrb/documents/timer.html +43 -0
- data/lib/wrb/documents/toolbar.html +181 -0
- data/lib/wrb/documents/tooltip.html +131 -0
- data/lib/wrb/documents/trackbar.html +107 -0
- data/lib/wrb/documents/treeview.html +210 -0
- data/lib/wrb/documents/updown.html +85 -0
- data/lib/wrb/documents/wincontrol.html +258 -0
- data/lib/wrb/documents/window.html +499 -0
- data/lib/wrb/documents/wrb.css +228 -0
- data/lib/wrb/gmem.rb +26 -0
- data/lib/wrb/imecommon.rb +59 -0
- data/lib/wrb/listcommon.rb +185 -0
- data/lib/wrb/lzss.rb +126 -0
- data/lib/wrb/scrollinfo.rb +142 -0
- data/lib/wrb/toplevelcommon.rb +634 -0
- metadata +315 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/*
|
|
2
|
+
# Project WRB was forked from Project VisualuRuby(temp-name).
|
|
3
|
+
# Author of this project: BANJO Koyu <banjokoyu at gmail.com>
|
|
4
|
+
# The URL of this project: https://bitbucket.org/wrb/
|
|
5
|
+
#
|
|
6
|
+
# This is a ext-library part of WRB.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "rwin.h"
|
|
10
|
+
ULONG_PTR
|
|
11
|
+
rw_call_std_func_0(ULONG_PTR* arg){
|
|
12
|
+
return ((FARPROC)arg[0])();
|
|
13
|
+
}
|
|
14
|
+
ULONG_PTR
|
|
15
|
+
rw_call_std_func_1(ULONG_PTR* arg){
|
|
16
|
+
return ((FARPROC)arg[0])(arg[1]);
|
|
17
|
+
}
|
|
18
|
+
ULONG_PTR
|
|
19
|
+
rw_call_std_func_2(ULONG_PTR* arg){
|
|
20
|
+
return ((FARPROC)arg[0])(arg[1], arg[2]);
|
|
21
|
+
}
|
|
22
|
+
ULONG_PTR
|
|
23
|
+
rw_call_std_func_3(ULONG_PTR* arg){
|
|
24
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3]);
|
|
25
|
+
}
|
|
26
|
+
ULONG_PTR
|
|
27
|
+
rw_call_std_func_4(ULONG_PTR* arg){
|
|
28
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4]);
|
|
29
|
+
}
|
|
30
|
+
ULONG_PTR
|
|
31
|
+
rw_call_std_func_5(ULONG_PTR* arg){
|
|
32
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5]);
|
|
33
|
+
}
|
|
34
|
+
ULONG_PTR
|
|
35
|
+
rw_call_std_func_6(ULONG_PTR* arg){
|
|
36
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6]);
|
|
37
|
+
}
|
|
38
|
+
ULONG_PTR
|
|
39
|
+
rw_call_std_func_7(ULONG_PTR* arg){
|
|
40
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]);
|
|
41
|
+
}
|
|
42
|
+
ULONG_PTR
|
|
43
|
+
rw_call_std_func_8(ULONG_PTR* arg){
|
|
44
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8]);
|
|
45
|
+
}
|
|
46
|
+
ULONG_PTR
|
|
47
|
+
rw_call_std_func_9(ULONG_PTR* arg){
|
|
48
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
|
|
49
|
+
}
|
|
50
|
+
ULONG_PTR
|
|
51
|
+
rw_call_std_func_10(ULONG_PTR* arg){
|
|
52
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10]);
|
|
53
|
+
}
|
|
54
|
+
ULONG_PTR
|
|
55
|
+
rw_call_std_func_11(ULONG_PTR* arg){
|
|
56
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11]);
|
|
57
|
+
}
|
|
58
|
+
ULONG_PTR
|
|
59
|
+
rw_call_std_func_12(ULONG_PTR* arg){
|
|
60
|
+
return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#ifdef RWIN_USEMULTITHREAD
|
|
64
|
+
|
|
65
|
+
ULONG_PTR
|
|
66
|
+
rw_call_without_gvl_0(DWORD thread_id, FARPROC winproc){
|
|
67
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
68
|
+
return winproc();
|
|
69
|
+
}else{
|
|
70
|
+
ULONG_PTR stdcdata[1]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
71
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_0, stdcdata);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
ULONG_PTR
|
|
75
|
+
rw_call_without_gvl_1(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1){
|
|
76
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
77
|
+
return winproc(arg1);
|
|
78
|
+
}else{
|
|
79
|
+
ULONG_PTR stdcdata[2]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
80
|
+
stdcdata[1] = arg1;
|
|
81
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_1, stdcdata);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
ULONG_PTR
|
|
85
|
+
rw_call_without_gvl_2(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2){
|
|
86
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
87
|
+
return winproc(arg1, arg2);
|
|
88
|
+
}else{
|
|
89
|
+
ULONG_PTR stdcdata[3]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
90
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
91
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_2, stdcdata);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
ULONG_PTR
|
|
95
|
+
rw_call_without_gvl_3(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3){
|
|
96
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
97
|
+
return winproc(arg1, arg2, arg3);
|
|
98
|
+
}else{
|
|
99
|
+
ULONG_PTR stdcdata[4]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
100
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
101
|
+
stdcdata[3] = arg3;
|
|
102
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_3, stdcdata);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
ULONG_PTR
|
|
106
|
+
rw_call_without_gvl_4(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4){
|
|
107
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
108
|
+
return winproc(arg1, arg2, arg3, arg4);
|
|
109
|
+
}else{
|
|
110
|
+
ULONG_PTR stdcdata[5]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
111
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
112
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
113
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_4, stdcdata);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
ULONG_PTR
|
|
117
|
+
rw_call_without_gvl_5(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5){
|
|
118
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
119
|
+
return winproc(arg1, arg2, arg3, arg4, arg5);
|
|
120
|
+
}else{
|
|
121
|
+
ULONG_PTR stdcdata[6]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
122
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
123
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
124
|
+
stdcdata[5] = arg5;
|
|
125
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_5, stdcdata);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
ULONG_PTR
|
|
129
|
+
rw_call_without_gvl_6(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6){
|
|
130
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
131
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6);
|
|
132
|
+
}else{
|
|
133
|
+
ULONG_PTR stdcdata[7]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
134
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
135
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
136
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
137
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_6, stdcdata);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
ULONG_PTR
|
|
141
|
+
rw_call_without_gvl_7(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7){
|
|
142
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
143
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
144
|
+
}else{
|
|
145
|
+
ULONG_PTR stdcdata[8]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
146
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
147
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
148
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
149
|
+
stdcdata[7] = arg7;
|
|
150
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_7, stdcdata);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
ULONG_PTR
|
|
154
|
+
rw_call_without_gvl_8(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8){
|
|
155
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
156
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
|
157
|
+
}else{
|
|
158
|
+
ULONG_PTR stdcdata[9]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
159
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
160
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
161
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
162
|
+
stdcdata[7] = arg7; stdcdata[8] = arg8;
|
|
163
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_8, stdcdata);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
ULONG_PTR
|
|
167
|
+
rw_call_without_gvl_9(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9){
|
|
168
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
169
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
|
170
|
+
}else{
|
|
171
|
+
ULONG_PTR stdcdata[10]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
172
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
173
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
174
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
175
|
+
stdcdata[7] = arg7; stdcdata[8] = arg8;
|
|
176
|
+
stdcdata[9] = arg9;
|
|
177
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_9, stdcdata);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
ULONG_PTR
|
|
181
|
+
rw_call_without_gvl_10(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10){
|
|
182
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
183
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
|
184
|
+
}else{
|
|
185
|
+
ULONG_PTR stdcdata[11]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
186
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
187
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
188
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
189
|
+
stdcdata[7] = arg7; stdcdata[8] = arg8;
|
|
190
|
+
stdcdata[9] = arg9; stdcdata[10] = arg10;
|
|
191
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_10, stdcdata);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
ULONG_PTR
|
|
195
|
+
rw_call_without_gvl_11(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11){
|
|
196
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
197
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
|
198
|
+
}else{
|
|
199
|
+
ULONG_PTR stdcdata[12]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
200
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
201
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
202
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
203
|
+
stdcdata[7] = arg7; stdcdata[8] = arg8;
|
|
204
|
+
stdcdata[9] = arg9; stdcdata[10] = arg10;
|
|
205
|
+
stdcdata[11] = arg11;
|
|
206
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_11, stdcdata);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
ULONG_PTR
|
|
210
|
+
rw_call_without_gvl_12(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12){
|
|
211
|
+
if(thread_id == GetCurrentThreadId()) {
|
|
212
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
|
213
|
+
}else{
|
|
214
|
+
ULONG_PTR stdcdata[13]; stdcdata[0] = (ULONG_PTR)winproc;
|
|
215
|
+
stdcdata[1] = arg1; stdcdata[2] = arg2;
|
|
216
|
+
stdcdata[3] = arg3; stdcdata[4] = arg4;
|
|
217
|
+
stdcdata[5] = arg5; stdcdata[6] = arg6;
|
|
218
|
+
stdcdata[7] = arg7; stdcdata[8] = arg8;
|
|
219
|
+
stdcdata[9] = arg9; stdcdata[10] = arg10;
|
|
220
|
+
stdcdata[11] = arg11; stdcdata[12] = arg12;
|
|
221
|
+
return CALL_NON_GVL_FUNC(rw_call_std_func_12, stdcdata);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#else
|
|
226
|
+
|
|
227
|
+
ULONG_PTR
|
|
228
|
+
rw_call_without_gvl_0(DWORD thread_id, FARPROC winproc){
|
|
229
|
+
return winproc();
|
|
230
|
+
}
|
|
231
|
+
ULONG_PTR
|
|
232
|
+
rw_call_without_gvl_1(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1){
|
|
233
|
+
return winproc(arg1);
|
|
234
|
+
}
|
|
235
|
+
ULONG_PTR
|
|
236
|
+
rw_call_without_gvl_2(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2){
|
|
237
|
+
return winproc(arg1, arg2);
|
|
238
|
+
}
|
|
239
|
+
ULONG_PTR
|
|
240
|
+
rw_call_without_gvl_3(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3){
|
|
241
|
+
return winproc(arg1, arg2, arg3);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
ULONG_PTR
|
|
245
|
+
rw_call_without_gvl_4(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4){
|
|
246
|
+
return winproc(arg1, arg2, arg3, arg4);
|
|
247
|
+
}
|
|
248
|
+
ULONG_PTR
|
|
249
|
+
rw_call_without_gvl_5(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5){
|
|
250
|
+
return winproc(arg1, arg2, arg3, arg4, arg5);
|
|
251
|
+
}
|
|
252
|
+
ULONG_PTR
|
|
253
|
+
rw_call_without_gvl_6(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6){
|
|
254
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6);
|
|
255
|
+
}
|
|
256
|
+
ULONG_PTR
|
|
257
|
+
rw_call_without_gvl_7(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7){
|
|
258
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
259
|
+
}
|
|
260
|
+
ULONG_PTR
|
|
261
|
+
rw_call_without_gvl_8(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8){
|
|
262
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
|
263
|
+
}
|
|
264
|
+
ULONG_PTR
|
|
265
|
+
rw_call_without_gvl_9(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9){
|
|
266
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
|
267
|
+
}
|
|
268
|
+
ULONG_PTR
|
|
269
|
+
rw_call_without_gvl_10(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10){
|
|
270
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
|
271
|
+
}
|
|
272
|
+
ULONG_PTR
|
|
273
|
+
rw_call_without_gvl_11(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11){
|
|
274
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
|
275
|
+
}
|
|
276
|
+
ULONG_PTR
|
|
277
|
+
rw_call_without_gvl_12(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12){
|
|
278
|
+
return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
#endif
|
|
@@ -0,0 +1,1936 @@
|
|
|
1
|
+
/*
|
|
2
|
+
# Project WRB was forked from Project VisualuRuby(temp-name).
|
|
3
|
+
# Author of this project: BANJO Koyu <banjokoyu at gmail.com>
|
|
4
|
+
# The URL of this project: https://bitbucket.org/wrb/
|
|
5
|
+
#
|
|
6
|
+
# This is a ext-library part of WRB.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "rwin.h"
|
|
10
|
+
|
|
11
|
+
VALUE cRwWindow;
|
|
12
|
+
|
|
13
|
+
/* TypedData */
|
|
14
|
+
void rw_win_free(void *ptr){
|
|
15
|
+
RwWindow *rw = ptr;
|
|
16
|
+
if (rw->hwnd) DestroyWindow(rw->hwnd);
|
|
17
|
+
if (rw->msgfilter) freeAAtree(rw->msgfilter);
|
|
18
|
+
if (rw->handler_ids) freeAAtree(rw->handler_ids);
|
|
19
|
+
if (rw->haccel) DestroyAcceleratorTable(rw->haccel);
|
|
20
|
+
free(rw);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static size_t
|
|
24
|
+
rwwin_memsize(const void *ptr){
|
|
25
|
+
return ptr ? sizeof(RwWindow) : 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const rb_data_type_t
|
|
29
|
+
rwwin_data_type = {
|
|
30
|
+
"Window", {NULL, rw_win_free, rwwin_memsize}, NULL, NULL
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
static VALUE
|
|
34
|
+
alloc_rw_window(VALUE klass){
|
|
35
|
+
RwWindow *rw;
|
|
36
|
+
VALUE obj;
|
|
37
|
+
obj = RwWindow_Data_Make_Struct(klass, rw);
|
|
38
|
+
|
|
39
|
+
rw->msgfilter = NULL;
|
|
40
|
+
rw->handler_ids = NULL;
|
|
41
|
+
rw->haccel = NULL;
|
|
42
|
+
return obj;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* message handler for RWin::Window */
|
|
46
|
+
|
|
47
|
+
static RwBaseHandler*
|
|
48
|
+
create_basehandler(RwMsgHandler *handler, AAtree *senders){
|
|
49
|
+
RwBaseHandler* basehandler;
|
|
50
|
+
RW_MALLOC(basehandler, sizeof(RwBaseHandler));
|
|
51
|
+
basehandler->handler = handler;
|
|
52
|
+
basehandler->senders = senders;
|
|
53
|
+
return basehandler;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void
|
|
57
|
+
free_msghandler(RwMsgHandler *handler){
|
|
58
|
+
if(handler->arg_template) free(handler->arg_template);
|
|
59
|
+
free(handler);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static RwMsgHandler*
|
|
63
|
+
alloc_msghandler(ID handler_id, VALUE v_klass, VALUE v_sendto){
|
|
64
|
+
RwMsgHandler *handler;
|
|
65
|
+
RW_CALLOC(handler, sizeof(RwMsgHandler));
|
|
66
|
+
handler->handler_id = handler_id;
|
|
67
|
+
handler->klass = v_klass;
|
|
68
|
+
handler->receiver = v_sendto;
|
|
69
|
+
handler->next = NULL;
|
|
70
|
+
return handler;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static RwMsgHandler*
|
|
74
|
+
create_msghandler(ID handler_id, VALUE v_template, VALUE v_klass, VALUE v_sendto){
|
|
75
|
+
RwMsgHandler *handler;
|
|
76
|
+
char *arg_template;
|
|
77
|
+
size_t len;
|
|
78
|
+
|
|
79
|
+
switch (TYPE(v_template)){
|
|
80
|
+
case T_NIL:
|
|
81
|
+
handler = alloc_msghandler(handler_id, v_klass, v_sendto);
|
|
82
|
+
handler->arg_template = NULL;
|
|
83
|
+
break;
|
|
84
|
+
case T_STRING:
|
|
85
|
+
handler = alloc_msghandler(handler_id, v_klass, v_sendto);
|
|
86
|
+
len = RSTRING_LEN(v_template);
|
|
87
|
+
if (len > 0) {
|
|
88
|
+
arg_template = malloc(len+1);
|
|
89
|
+
memcpy(arg_template, RSTRING_PTR(v_template), len);
|
|
90
|
+
arg_template[len] = 0;
|
|
91
|
+
handler->arg_template = arg_template;
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
rb_raise(rb_eArgError, "Template must be a String");
|
|
96
|
+
}
|
|
97
|
+
return handler;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static void
|
|
101
|
+
aa_destruct1(void* val){
|
|
102
|
+
if (val) freeAAtree((AAtree*)val);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static void
|
|
106
|
+
aa_destruct_handler(void* val){
|
|
107
|
+
RwMsgHandler *handler = val;
|
|
108
|
+
while(handler){
|
|
109
|
+
RwMsgHandler *hh = handler;
|
|
110
|
+
handler = handler->next;
|
|
111
|
+
free_msghandler(hh);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static void
|
|
116
|
+
aa_destruct_basehandler(void* val){
|
|
117
|
+
if (val) { /* delete all msgfilter */
|
|
118
|
+
RwBaseHandler *basehandler = val;
|
|
119
|
+
if (basehandler->senders) freeAAtree(basehandler->senders);
|
|
120
|
+
if (basehandler->handler) aa_destruct_handler(basehandler->handler);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
static void
|
|
125
|
+
rw_msgreceiver_add(VALUE receiver, ID handler_id){
|
|
126
|
+
AAnode *idnode;
|
|
127
|
+
RwWindow *rcv;
|
|
128
|
+
RwWindow_Data_Get_Struct(receiver, rcv);
|
|
129
|
+
if (!rcv->handler_ids) rcv->handler_ids = newAAtree(NULL);
|
|
130
|
+
if (idnode=aaSearch(rcv->handler_ids, handler_id)){
|
|
131
|
+
idnode->num++;
|
|
132
|
+
} else {
|
|
133
|
+
aaInsert(rcv->handler_ids, handler_id, 0);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static RwMsgHandler*
|
|
138
|
+
rw_append_handler(RwMsgHandler *handler, RwMsgHandler *newhandler){
|
|
139
|
+
RwMsgHandler *next;
|
|
140
|
+
RwMsgHandler *root = handler;
|
|
141
|
+
ID handler_id = newhandler->handler_id;
|
|
142
|
+
VALUE receiver = newhandler->receiver;
|
|
143
|
+
if (!handler) return newhandler;
|
|
144
|
+
if(handler->handler_id==handler_id && handler->receiver==receiver){
|
|
145
|
+
rb_raise(rb_eRuntimeError, "`%s' is already defined.", rb_id2name(handler_id));
|
|
146
|
+
}
|
|
147
|
+
while(next = handler->next){
|
|
148
|
+
if (next->handler_id == handler_id && next->receiver==receiver){
|
|
149
|
+
rb_raise(rb_eRuntimeError, "`%s' is already defined in destination.",
|
|
150
|
+
rb_id2name(handler_id));
|
|
151
|
+
}
|
|
152
|
+
if(handler->next) handler = handler->next;
|
|
153
|
+
}
|
|
154
|
+
rw_msgreceiver_add(receiver, newhandler->handler_id);
|
|
155
|
+
handler->next = newhandler; /* append data at last */
|
|
156
|
+
return root;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static void
|
|
160
|
+
add_simple_filter(AAtree *msgfilter, unsigned msg, RwMsgHandler *newhandler){
|
|
161
|
+
AAnode *node = aaSearch(msgfilter, msg);
|
|
162
|
+
if (node){
|
|
163
|
+
if (node->val) {
|
|
164
|
+
node->val = rw_append_handler((RwMsgHandler*)(node->val), newhandler);
|
|
165
|
+
} else {
|
|
166
|
+
rw_msgreceiver_add(newhandler->receiver, newhandler->handler_id);
|
|
167
|
+
node->val = newhandler;
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
rw_msgreceiver_add(newhandler->receiver, newhandler->handler_id);
|
|
171
|
+
aaInsert(msgfilter, msg, newhandler);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static VALUE
|
|
176
|
+
rwwin_msgtranslator_set(int argc, VALUE *argv, VALUE self){
|
|
177
|
+
int msg;
|
|
178
|
+
ID callback_id;
|
|
179
|
+
RwBaseHandler *basehandler;
|
|
180
|
+
VALUE v_msg, v_callback, v_template;
|
|
181
|
+
RwMsgHandler *newhandler;
|
|
182
|
+
|
|
183
|
+
RwWindow *rw = DATA_PTR(self);
|
|
184
|
+
rb_scan_args(argc, argv, "12", &v_msg, &v_callback, &v_template);
|
|
185
|
+
msg = FIX2INT(v_msg);
|
|
186
|
+
callback_id = NIL_P(v_callback) ? Qfalse : rb_to_id(v_callback);
|
|
187
|
+
if(rw->msgfilter) {
|
|
188
|
+
AAnode *ndbase = aaSearch(rw->msgfilter, msg);
|
|
189
|
+
if (ndbase){ /* Node must be empty. */
|
|
190
|
+
rb_raise(rb_eRuntimeError, "Already defined handler for msg: %#x", msg);
|
|
191
|
+
} else {
|
|
192
|
+
newhandler = create_msghandler(callback_id, v_template, Qfalse, Qfalse);
|
|
193
|
+
basehandler = create_basehandler(newhandler, newAAtree(aa_destruct1));
|
|
194
|
+
aaInsert(rw->msgfilter, msg, basehandler);
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
newhandler = create_msghandler(callback_id, v_template, Qfalse, Qfalse);
|
|
198
|
+
basehandler = create_basehandler(newhandler, newAAtree(aa_destruct1));
|
|
199
|
+
rw->msgfilter = newAAtree(aa_destruct_basehandler);
|
|
200
|
+
aaInsert(rw->msgfilter, msg, basehandler);
|
|
201
|
+
}
|
|
202
|
+
return Qnil;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
static VALUE
|
|
206
|
+
rwwin_msgtranslator_get(VALUE self, VALUE v_msg){
|
|
207
|
+
AAnode *node;
|
|
208
|
+
int msg = FIX2INT(v_msg);
|
|
209
|
+
RwWindow *rw = DATA_PTR(self);
|
|
210
|
+
if (!rw->msgfilter) return Qnil;
|
|
211
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
212
|
+
if(node){
|
|
213
|
+
RwBaseHandler *basehandler = node->val;
|
|
214
|
+
if (basehandler->senders){
|
|
215
|
+
return INT2FIX(basehandler->handler->handler_id);
|
|
216
|
+
} else {
|
|
217
|
+
rb_raise(rb_eRuntimeError, "Already defined handler for msg: %#x", msg);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return Qnil;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
static VALUE
|
|
224
|
+
rwwin_msgfilter_add(int argc, VALUE *argv, VALUE self){
|
|
225
|
+
RwBaseHandler *basehandler;
|
|
226
|
+
RwMsgHandler *newhandler;
|
|
227
|
+
unsigned msg, submsg;
|
|
228
|
+
ID handler_id;
|
|
229
|
+
int etc;
|
|
230
|
+
VALUE v_msg, v_submsg, v_etc, v_handler, v_template, v_sendto, v_klass;
|
|
231
|
+
|
|
232
|
+
RwWindow *rw = DATA_PTR(self);
|
|
233
|
+
v_sendto = self;
|
|
234
|
+
v_template = Qnil;
|
|
235
|
+
v_klass = Qnil;
|
|
236
|
+
while (NIL_P(argv[argc-1])){ /* reject last nil */
|
|
237
|
+
argc--;
|
|
238
|
+
}
|
|
239
|
+
if (rb_typeddata_is_kind_of(argv[argc-1], &rwwin_data_type)){
|
|
240
|
+
/* message forwarding (sends message to any target window) */
|
|
241
|
+
v_sendto = argv[argc-1];
|
|
242
|
+
argc -= 1;
|
|
243
|
+
}
|
|
244
|
+
if (NIL_P(argv[argc-1])) {
|
|
245
|
+
argc -= 1;
|
|
246
|
+
} else if (rb_obj_class(argv[argc-1])==rb_cClass &&
|
|
247
|
+
(rb_class_inherited_p(argv[argc-1], cRwAPIstruct)==Qtrue ||
|
|
248
|
+
rb_class_inherited_p(argv[argc-1], cRwCanvas)==Qtrue)){
|
|
249
|
+
/* lParam is CStruct or Canvas*/
|
|
250
|
+
v_klass = argv[argc-1];
|
|
251
|
+
argc -= 1;
|
|
252
|
+
}
|
|
253
|
+
if(argc > 3){ /* for WM_COMMAND / WM_NOTIFY (supports message which from Menu)*/
|
|
254
|
+
rb_scan_args(argc, argv, "41", &v_etc, &v_msg, &v_submsg, &v_handler, &v_template);
|
|
255
|
+
etc = NUM2INT(v_etc);
|
|
256
|
+
} else { /* for simple message forwarding*/
|
|
257
|
+
rb_scan_args(argc, argv, "21", &v_msg, &v_handler, &v_template);
|
|
258
|
+
v_submsg = Qnil;
|
|
259
|
+
etc = 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
msg = NUM2UINT(v_msg);
|
|
263
|
+
if (!NIL_P(v_submsg)){
|
|
264
|
+
if(NIL_P(rwwin_msgtranslator_get(self, v_msg))){
|
|
265
|
+
rb_raise(rb_eRuntimeError, "Translator of message 0x%x is not defined", msg);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
submsg = NIL_P(v_submsg) ? 0 : NUM2UINT(v_submsg);
|
|
269
|
+
handler_id = rb_to_id(v_handler);
|
|
270
|
+
|
|
271
|
+
if (!NIL_P(v_template)){ /* check template */
|
|
272
|
+
int len = RSTRING_LEN(v_template);
|
|
273
|
+
char* tmpl = RSTRING_PTR(v_template);
|
|
274
|
+
switch(tmpl[0]){
|
|
275
|
+
case 'h': case 'i': case 'x':
|
|
276
|
+
break;
|
|
277
|
+
case 'c':
|
|
278
|
+
if(msg!=WM_PAINT) rb_raise(rb_eRuntimeError, "Template 'c' is only for WM_PAINT");
|
|
279
|
+
if (NIL_P(v_klass)){
|
|
280
|
+
v_klass = cRwCanvas;
|
|
281
|
+
} else if(NIL_P(rb_class_inherited_p(cRwCanvas, v_klass))){
|
|
282
|
+
rb_raise(rb_eRuntimeError, "Need Canvas inherited class for template 'c'");
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
case 's':
|
|
286
|
+
rb_raise(rb_eRuntimeError, "Template 's' is only for lParam");
|
|
287
|
+
default:
|
|
288
|
+
rb_raise(rb_eRuntimeError, "Unknown template `%c' for wParam", tmpl[0]);
|
|
289
|
+
}
|
|
290
|
+
if (len>1) switch(tmpl[1]){
|
|
291
|
+
case 'h': case 'i': case 'x':
|
|
292
|
+
break;
|
|
293
|
+
case 's':
|
|
294
|
+
if (NIL_P(v_klass) || NIL_P(rb_class_inherited_p(cRwAPIstruct, v_klass))){
|
|
295
|
+
rb_raise(rb_eRuntimeError, "Need CSruct inherited class for template 's'");
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
default:
|
|
299
|
+
rb_raise(rb_eRuntimeError, "Unknown template `%c' for lParam", tmpl[1]);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
newhandler = create_msghandler(handler_id, v_template, v_klass, v_sendto);
|
|
304
|
+
if (!etc){
|
|
305
|
+
if(rw->msgfilter) {
|
|
306
|
+
AAnode *node = aaSearch(rw->msgfilter, msg);
|
|
307
|
+
if (node){
|
|
308
|
+
basehandler = node->val;
|
|
309
|
+
if (basehandler->handler){
|
|
310
|
+
basehandler->handler = rw_append_handler(basehandler->handler, newhandler);
|
|
311
|
+
} else {
|
|
312
|
+
rw_msgreceiver_add(newhandler->receiver, newhandler->handler_id);
|
|
313
|
+
basehandler->handler = newhandler;
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
rw_msgreceiver_add(v_sendto, handler_id);
|
|
317
|
+
basehandler = create_basehandler(newhandler, NULL);
|
|
318
|
+
aaInsert(rw->msgfilter, msg, basehandler);
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
rw_msgreceiver_add(v_sendto, handler_id);
|
|
322
|
+
basehandler = create_basehandler(newhandler, NULL);
|
|
323
|
+
rw->msgfilter = newAAtree(aa_destruct_basehandler);
|
|
324
|
+
aaInsert(rw->msgfilter, msg, basehandler);
|
|
325
|
+
}
|
|
326
|
+
} else {
|
|
327
|
+
if(rw->msgfilter) {
|
|
328
|
+
AAnode *ndbase = aaSearch(rw->msgfilter, msg);
|
|
329
|
+
if (ndbase){
|
|
330
|
+
AAnode *ndsubfilter;
|
|
331
|
+
RwMsgHandler *subhandler;
|
|
332
|
+
subhandler = create_msghandler(handler_id, v_template, v_klass, v_sendto);
|
|
333
|
+
basehandler = ndbase->val;
|
|
334
|
+
ndsubfilter = aaSearch(basehandler->senders, etc);
|
|
335
|
+
if (ndsubfilter){
|
|
336
|
+
add_simple_filter(ndsubfilter->val, submsg, subhandler);
|
|
337
|
+
} else {
|
|
338
|
+
AAtree *subfilter = newAAtree(aa_destruct_handler);
|
|
339
|
+
rw_msgreceiver_add(v_sendto, handler_id);
|
|
340
|
+
aaInsert(basehandler->senders, etc, subfilter);
|
|
341
|
+
aaInsert(subfilter, submsg, subhandler);
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
rb_raise(rb_eRuntimeError, "Translator is not defined");
|
|
345
|
+
}
|
|
346
|
+
} else {
|
|
347
|
+
rb_raise(rb_eRuntimeError, "Translator is not defined");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return v_msg;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
static AAtree*
|
|
354
|
+
delete_handler_ids(AAtree *tree, ID handler_id){
|
|
355
|
+
AAnode *nd = aaSearch(tree, handler_id);
|
|
356
|
+
if (nd) {
|
|
357
|
+
if(!nd->num) {
|
|
358
|
+
aaDelete(tree, handler_id);
|
|
359
|
+
} else {
|
|
360
|
+
nd->num--;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return tree;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
static void*
|
|
367
|
+
delete_msghandler(RwWindow *rw, RwMsgHandler *handler, ID id, VALUE receiver){
|
|
368
|
+
RwMsgHandler *next;
|
|
369
|
+
RwMsgHandler *root = handler;
|
|
370
|
+
if(handler->handler_id == id){
|
|
371
|
+
if(rw->handler_ids) rw->handler_ids = delete_handler_ids(rw->handler_ids, id);
|
|
372
|
+
root = handler->next;
|
|
373
|
+
free_msghandler(handler);
|
|
374
|
+
} else {
|
|
375
|
+
while(next = handler->next){
|
|
376
|
+
if (next->handler_id == id && next->receiver==receiver){
|
|
377
|
+
rw->handler_ids = delete_handler_ids(rw->handler_ids, id);
|
|
378
|
+
handler->next = next->next;
|
|
379
|
+
free_msghandler(next);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
handler = handler->next;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return root;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/*
|
|
389
|
+
static void
|
|
390
|
+
aa_debug_callback(const AAnode *node, void *arg) {
|
|
391
|
+
fprintf(stderr, "%s key %d, val %d, lv %d\n", (char*)arg, node->key, (int)node->val, node->level);
|
|
392
|
+
}
|
|
393
|
+
*/
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
static void
|
|
397
|
+
aa_delete_handler_id(const AAnode *nd, void *arg){
|
|
398
|
+
RwMsgHandler *handler = nd->val;
|
|
399
|
+
AAtree *tree = ((RwWindow*)arg)->handler_ids;// fprintf(stderr, "@439:tree=%x\n",tree);
|
|
400
|
+
if (!tree) return;
|
|
401
|
+
while(handler){
|
|
402
|
+
delete_handler_ids(tree, handler->handler_id);
|
|
403
|
+
handler = handler->next;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
static void
|
|
408
|
+
aa_aa_delete_id_of_senders(const AAnode *nd, void *arg){
|
|
409
|
+
aaForeach(nd->val, aa_delete_handler_id, arg);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
static VALUE
|
|
413
|
+
rwwin_msgfilter_delete(int argc, VALUE *argv, VALUE self){
|
|
414
|
+
VALUE v_sendto;
|
|
415
|
+
AAnode *node;
|
|
416
|
+
RwBaseHandler *bhandler;
|
|
417
|
+
RwWindow *rw = DATA_PTR(self);
|
|
418
|
+
if (!rw->msgfilter) return Qnil;
|
|
419
|
+
if (argc==1){ // Need to add a case when only one control was given.
|
|
420
|
+
int msg = NUM2INT(argv[0]);
|
|
421
|
+
if (node=aaSearch(rw->msgfilter, msg)){
|
|
422
|
+
RwBaseHandler *bhandler = node->val;
|
|
423
|
+
if(bhandler->handler){
|
|
424
|
+
RwMsgHandler *hd;
|
|
425
|
+
while(hd=bhandler->handler){
|
|
426
|
+
bhandler->handler = delete_msghandler(rw, bhandler->handler, hd->handler_id,
|
|
427
|
+
Qfalse);
|
|
428
|
+
rw->handler_ids = delete_handler_ids(rw->handler_ids, hd->handler_id);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if(bhandler->senders) aaForeach(bhandler->senders, aa_aa_delete_id_of_senders, rw);
|
|
432
|
+
aaDelete(rw->msgfilter, msg);
|
|
433
|
+
return Qtrue;
|
|
434
|
+
} else {
|
|
435
|
+
return Qnil;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if(argc > 1 && rb_typeddata_is_kind_of(argv[argc-1], &rwwin_data_type)){
|
|
440
|
+
v_sendto = Qnil;
|
|
441
|
+
argc--;
|
|
442
|
+
} else {
|
|
443
|
+
v_sendto = Qfalse;
|
|
444
|
+
}
|
|
445
|
+
if(argc==2){
|
|
446
|
+
if (TYPE(argv[1])==T_STRING){ /* msg, handler_name */
|
|
447
|
+
ID handler_id;
|
|
448
|
+
int msg = FIX2INT(argv[0]);
|
|
449
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
450
|
+
if (!node || !(bhandler=node->val)) return Qnil;
|
|
451
|
+
if (!bhandler->handler) return Qnil;
|
|
452
|
+
handler_id = rb_to_id(argv[1]);
|
|
453
|
+
bhandler->handler = delete_msghandler(rw, bhandler->handler, handler_id, v_sendto);
|
|
454
|
+
if (!bhandler->handler && !bhandler->senders) aaDelete(rw->msgfilter, msg);
|
|
455
|
+
} else { /* idcmd, msg */
|
|
456
|
+
AAnode *nd;
|
|
457
|
+
int etc;
|
|
458
|
+
int msg = FIX2INT(argv[1]);
|
|
459
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
460
|
+
if (!node) return Qnil;
|
|
461
|
+
bhandler = node->val;
|
|
462
|
+
etc = FIX2INT(argv[0]);
|
|
463
|
+
if(!bhandler->senders) return Qnil;
|
|
464
|
+
if(nd = aaSearch(bhandler->senders, etc)){
|
|
465
|
+
aaForeach(nd->val, aa_delete_handler_id, rw);
|
|
466
|
+
aaDelete(bhandler->senders, etc);
|
|
467
|
+
} else {
|
|
468
|
+
return Qfalse;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
} else if(argc==3 || argc==4) { /* 3..4 */
|
|
472
|
+
AAnode *ndsubfilter;
|
|
473
|
+
AAnode *ndsubhandler;
|
|
474
|
+
int etc, submsg;
|
|
475
|
+
int msg = FIX2INT(argv[1]);
|
|
476
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
477
|
+
if (!node) return Qnil;
|
|
478
|
+
bhandler = node->val;
|
|
479
|
+
if(!bhandler->senders){
|
|
480
|
+
rb_raise(rb_eArgError, "MsgTranslator of message:0x%x is not defined", msg);
|
|
481
|
+
}
|
|
482
|
+
etc = FIX2INT(argv[0]);
|
|
483
|
+
submsg = FIX2INT(argv[2]);
|
|
484
|
+
ndsubfilter = aaSearch(bhandler->senders, etc);
|
|
485
|
+
if(!ndsubfilter) return Qnil;
|
|
486
|
+
ndsubhandler = aaSearch(ndsubfilter->val, submsg);
|
|
487
|
+
if (!ndsubhandler || !ndsubhandler->val) return Qnil;
|
|
488
|
+
if(argc==3) {
|
|
489
|
+
aaForeach(ndsubfilter->val, aa_delete_handler_id, rw);
|
|
490
|
+
aaDelete(ndsubfilter->val, submsg);
|
|
491
|
+
} else { /* argc == 4 */
|
|
492
|
+
RwMsgHandler *subhandler = ndsubhandler->val;
|
|
493
|
+
ID sub_id = rb_to_id(argv[3]); //fprintf(stderr, "sub_id=%x\n", sub_id);
|
|
494
|
+
ndsubhandler->val = delete_msghandler(rw, subhandler, sub_id, v_sendto);
|
|
495
|
+
}
|
|
496
|
+
} else {
|
|
497
|
+
rb_raise(rb_eArgError, "argments must be 1..5");
|
|
498
|
+
}
|
|
499
|
+
return Qtrue;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
static VALUE
|
|
503
|
+
search_msghandler(RwWindow *rw, RwMsgHandler *handler, ID id, VALUE receiver){
|
|
504
|
+
RwMsgHandler *next;
|
|
505
|
+
if(handler->handler_id == id) return Qtrue;
|
|
506
|
+
while(next = handler->next){
|
|
507
|
+
if (next->handler_id == id && next->receiver==receiver) return Qtrue;
|
|
508
|
+
handler = handler->next;
|
|
509
|
+
}
|
|
510
|
+
return Qfalse;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
static VALUE
|
|
514
|
+
rwwin_msgfilter_exist_p(int argc, VALUE *argv, VALUE self){
|
|
515
|
+
int msg, etc;
|
|
516
|
+
VALUE v_sendto;
|
|
517
|
+
AAnode *node;
|
|
518
|
+
RwBaseHandler *bhandler;
|
|
519
|
+
RwWindow *rw = DATA_PTR(self);
|
|
520
|
+
if (!rw->msgfilter) return Qfalse;
|
|
521
|
+
if(argc > 1 && rb_typeddata_is_kind_of(argv[argc-1], &rwwin_data_type)){
|
|
522
|
+
v_sendto = Qfalse;
|
|
523
|
+
argc--;
|
|
524
|
+
} else {
|
|
525
|
+
v_sendto = Qfalse;
|
|
526
|
+
}
|
|
527
|
+
if (argc==1){
|
|
528
|
+
msg = FIX2INT(argv[0]);
|
|
529
|
+
return aaSearch(rw->msgfilter, msg) ? Qtrue : Qfalse;
|
|
530
|
+
}else if(argc==2){
|
|
531
|
+
if (TYPE(argv[1])==T_STRING){ /* msg, handler_name */
|
|
532
|
+
ID handler_id;
|
|
533
|
+
msg = FIX2INT(argv[0]);
|
|
534
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
535
|
+
if (!node || !node->val) return Qfalse;
|
|
536
|
+
bhandler = node->val;
|
|
537
|
+
if (!bhandler->handler) return Qfalse;
|
|
538
|
+
handler_id = rb_to_id(argv[1]);
|
|
539
|
+
return search_msghandler(rw, bhandler->handler, handler_id, v_sendto);
|
|
540
|
+
} else { /* idcmd, msg */
|
|
541
|
+
msg = FIX2INT(argv[1]);
|
|
542
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
543
|
+
if (!node) return Qfalse;
|
|
544
|
+
bhandler = node->val; //fprintf(stderr, "@%d\n", __LINE__);
|
|
545
|
+
if (!bhandler->senders) return Qfalse; // fprintf(stderr, "@%d, %xll\n", __LINE__, (ULONG_PTR)bhandler->senders);
|
|
546
|
+
etc = FIX2INT(argv[0]);
|
|
547
|
+
return aaSearch(bhandler->senders, etc) ? Qtrue : Qfalse;
|
|
548
|
+
}
|
|
549
|
+
} else if(argc==3 || argc==4) { /* 3..4 */
|
|
550
|
+
AAnode *ndsubfilter;
|
|
551
|
+
AAnode *ndsubhandler;
|
|
552
|
+
int submsg;
|
|
553
|
+
|
|
554
|
+
msg = FIX2INT(argv[1]);
|
|
555
|
+
node = aaSearch(rw->msgfilter, msg);
|
|
556
|
+
if (!node) return Qfalse;
|
|
557
|
+
bhandler = node->val;
|
|
558
|
+
if(!bhandler->handler||!bhandler->senders) return Qfalse;
|
|
559
|
+
etc = FIX2INT(argv[0]);
|
|
560
|
+
submsg = FIX2INT(argv[2]);
|
|
561
|
+
ndsubfilter = aaSearch(bhandler->senders, etc);
|
|
562
|
+
if(!ndsubfilter) return Qfalse;
|
|
563
|
+
ndsubhandler = aaSearch(ndsubfilter->val, submsg);
|
|
564
|
+
if (!ndsubhandler || !ndsubhandler->val) return Qfalse;
|
|
565
|
+
if(argc==3) {
|
|
566
|
+
return Qtrue;
|
|
567
|
+
} else { /* argc == 4 */
|
|
568
|
+
RwMsgHandler *subhandler = ndsubhandler->val;
|
|
569
|
+
ID sub_id = rb_to_id(argv[3]);
|
|
570
|
+
return search_msghandler(rw, subhandler, sub_id, v_sendto);
|
|
571
|
+
}
|
|
572
|
+
} else {
|
|
573
|
+
rb_raise(rb_eArgError, "argments must be 1..5");
|
|
574
|
+
}
|
|
575
|
+
return Qfalse;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
void
|
|
579
|
+
aa_callback_each_msgfilter(const AAnode *node, void *arg){
|
|
580
|
+
VALUE ar = (VALUE)arg;
|
|
581
|
+
rb_ary_push(ar, INT2NUM(node->key));
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
static VALUE
|
|
585
|
+
rwwin_msgfilter_getfilters(VALUE self){
|
|
586
|
+
RwWindow *rw = DATA_PTR(self);
|
|
587
|
+
VALUE ary = rb_ary_new();
|
|
588
|
+
aaForeach(rw->msgfilter, aa_callback_each_msgfilter, (void*)ary);
|
|
589
|
+
return ary;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/* prototyping */
|
|
593
|
+
LRESULT CALLBACK RwSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
|
594
|
+
|
|
595
|
+
static VALUE
|
|
596
|
+
rwwin_create(int argc,VALUE* argv, VALUE self){
|
|
597
|
+
TCHAR *classname, *caption;
|
|
598
|
+
RwWindow *rw = DATA_PTR(self);
|
|
599
|
+
HWND hparent = NULL;
|
|
600
|
+
|
|
601
|
+
if(TYPE(argv[0])==T_STRING) {
|
|
602
|
+
classname = rw_str2tchar(argv[0]);
|
|
603
|
+
} else{
|
|
604
|
+
rb_raise(rb_eArgError, "1st argument must be class name(String)");
|
|
605
|
+
}
|
|
606
|
+
if(TYPE(argv[1])==T_STRING) {
|
|
607
|
+
caption = rw_str2tchar(argv[1]);
|
|
608
|
+
} else{
|
|
609
|
+
rb_raise(rb_eArgError, "2nd argument must be caption(String)");
|
|
610
|
+
}
|
|
611
|
+
if (!NIL_P(argv[6])){
|
|
612
|
+
RwWindow *rwparent;
|
|
613
|
+
RwWindow_Data_Get_Struct(argv[6], rwparent);
|
|
614
|
+
hparent = rwparent->hwnd;
|
|
615
|
+
}
|
|
616
|
+
rw->hwnd = CreateWindowEx(NUM2UINT(argv[9]), /* dwExStyle */
|
|
617
|
+
classname,
|
|
618
|
+
caption,
|
|
619
|
+
NUM2UINT(argv[8]), /* dwStyle */
|
|
620
|
+
NUM2INT(argv[2]), /* x */
|
|
621
|
+
NUM2INT(argv[3]), /* y */
|
|
622
|
+
NUM2INT(argv[4]), /* w */
|
|
623
|
+
NUM2INT(argv[5]), /* h */
|
|
624
|
+
hparent, /* hParent */
|
|
625
|
+
NIL_P(argv[7]) ? 0 : (HMENU)NUM2ULONG_PTR(argv[7]), /* hMenu */
|
|
626
|
+
hInstance,
|
|
627
|
+
NULL);
|
|
628
|
+
if(!rw->hwnd){
|
|
629
|
+
rb_raise(rb_eRuntimeError, "failed to create window(%s)", RSTRING_PTR(argv[0]));
|
|
630
|
+
}
|
|
631
|
+
rw->nthread_id = GetCurrentThreadId();
|
|
632
|
+
if(hparent){
|
|
633
|
+
Register_childwin(rw->hwnd, self);
|
|
634
|
+
if(GetClassLong(rw->hwnd, GCW_ATOM)==RwClassAtom){
|
|
635
|
+
int id = NIL_P(argv[7]) ? 0 : FIX2INT(argv[7]);
|
|
636
|
+
SetWindowSubclass(rw->hwnd, RwSubclassProc, (UINT_PTR)id, (DWORD_PTR)self);
|
|
637
|
+
}
|
|
638
|
+
} else {
|
|
639
|
+
Register_win(rw->hwnd, self);
|
|
640
|
+
if (GetActiveWindow()==rw->hwnd) activewin = rw;
|
|
641
|
+
}
|
|
642
|
+
return self;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
static VALUE
|
|
646
|
+
rwwin1_new_from_handle(VALUE klass, VALUE v_handle){
|
|
647
|
+
RwWindow *rw;
|
|
648
|
+
VALUE obj;
|
|
649
|
+
HANDLE handle = (HANDLE)NUM2ULONG_PTR(v_handle);
|
|
650
|
+
if(!GetParent(handle)) rb_raise(rb_eArgError,
|
|
651
|
+
"Handle %#x is not child window", (int)(ULONG_PTR)handle);
|
|
652
|
+
|
|
653
|
+
obj = RwWindow_Data_Make_Struct(klass, rw);
|
|
654
|
+
rw->hwnd = handle;
|
|
655
|
+
rw->msgfilter = NULL;
|
|
656
|
+
rw->handler_ids = NULL;
|
|
657
|
+
rw->haccel = NULL;
|
|
658
|
+
Register_childwin(rw->hwnd, obj);
|
|
659
|
+
return obj;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/* Event handling routines */
|
|
663
|
+
static VALUE
|
|
664
|
+
rw_method_missing(int argc, VALUE *argv, VALUE self){
|
|
665
|
+
ID method_id = rb_to_id(argv[0]);
|
|
666
|
+
RwWindow *rw = DATA_PTR(self);
|
|
667
|
+
if(rw->handler_ids && aaSearch(rw->handler_ids, method_id)) return Qnil;
|
|
668
|
+
rb_call_super(argc, argv);
|
|
669
|
+
return Qnil;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/* Keyborad accelarators */
|
|
673
|
+
static VALUE
|
|
674
|
+
rw_set_accelerator(VALUE self, VALUE v_acceltable){
|
|
675
|
+
int len, i;
|
|
676
|
+
HACCEL haccel = NULL;
|
|
677
|
+
ACCEL *paccel = NULL;
|
|
678
|
+
RwWindow *rw = DATA_PTR(self);
|
|
679
|
+
if (NIL_P(v_acceltable)){
|
|
680
|
+
if(rw->haccel) DestroyAcceleratorTable(rw->haccel);
|
|
681
|
+
rw->haccel = NULL;
|
|
682
|
+
return Qnil;
|
|
683
|
+
}
|
|
684
|
+
if(TYPE(v_acceltable)!=T_ARRAY) rb_raise(rb_eArgError, "Argument must be an Array.");
|
|
685
|
+
len = RARRAY_LEN(v_acceltable);
|
|
686
|
+
if(rw->haccel) DestroyAcceleratorTable(rw->haccel);
|
|
687
|
+
RW_MALLOC(paccel, len*sizeof(ACCEL));
|
|
688
|
+
for(i=0; i<len; i++){
|
|
689
|
+
VALUE v_accel = rb_ary_entry(v_acceltable, i);
|
|
690
|
+
paccel[i].fVirt = FIX2INT(rb_ary_entry(v_accel, 0));
|
|
691
|
+
paccel[i].key = FIX2INT(rb_ary_entry(v_accel, 1));
|
|
692
|
+
paccel[i].cmd = FIX2INT(rb_ary_entry(v_accel, 2));
|
|
693
|
+
}
|
|
694
|
+
haccel = CreateAcceleratorTable(paccel, len);
|
|
695
|
+
if(!haccel) rb_raise(rb_eRuntimeError, "CreateAcceleratorTable faled.");
|
|
696
|
+
rw->haccel = haccel;
|
|
697
|
+
free(paccel);
|
|
698
|
+
return INT2FIX(len);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/* Error handling routines */
|
|
702
|
+
void
|
|
703
|
+
rw_abort_program(int state){
|
|
704
|
+
VALUE bt, bt0, msg;
|
|
705
|
+
VALUE e = rb_errinfo();
|
|
706
|
+
char btbuff[4096] = "";
|
|
707
|
+
int i, len;
|
|
708
|
+
|
|
709
|
+
bt = rb_funcall(e, rb_intern("backtrace"), 0);
|
|
710
|
+
msg = rb_funcall(e, rb_intern("message"), 0);
|
|
711
|
+
bt0 = rb_ary_shift(bt);
|
|
712
|
+
len = RARRAY_LEN(bt);
|
|
713
|
+
|
|
714
|
+
for(i=0; i<len; i++){
|
|
715
|
+
VALUE btn = rb_ary_entry(bt, i);
|
|
716
|
+
char* btstr = StringValuePtr(btn);
|
|
717
|
+
strcat(btbuff, "from: ");
|
|
718
|
+
strcat(btbuff, btstr);
|
|
719
|
+
strcat(btbuff, "\n");
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if(IS_GUIAPP){
|
|
723
|
+
char buff[4096];
|
|
724
|
+
sprintf(buff, "message: %s\n\nat: %s\n%s",
|
|
725
|
+
StringValuePtr(msg), StringValuePtr(bt0), btbuff);
|
|
726
|
+
MessageBoxA(NULL, buff, rb_obj_classname(e), 16);
|
|
727
|
+
PostQuitMessage(state);
|
|
728
|
+
} else {
|
|
729
|
+
fprintf(stderr, "Error occurred during message handling\n%s: %s (%s)\nfrom: %s",
|
|
730
|
+
StringValuePtr(bt0), StringValuePtr(msg), rb_obj_classname(e), btbuff);
|
|
731
|
+
PostQuitMessage(state);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
static VALUE
|
|
736
|
+
rw_funcall_0(VALUE args){
|
|
737
|
+
VALUE *parg = (VALUE*)args;
|
|
738
|
+
return rb_funcall(parg[0], parg[1], 0);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
static VALUE
|
|
742
|
+
rw_funcall_1(VALUE args){
|
|
743
|
+
VALUE *parg = (VALUE*)args;
|
|
744
|
+
return rb_funcall(parg[0], parg[1], 1, parg[2]);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
static VALUE
|
|
748
|
+
rw_funcall_n(VALUE args){
|
|
749
|
+
VALUE *parg = (VALUE*)args;
|
|
750
|
+
return rb_funcall2(parg[0], parg[1], parg[2], &parg[3]);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
void
|
|
754
|
+
dispatch_wm_paint_handler(VALUE wobj, RwBaseHandler *basehandler, HDC hdc){
|
|
755
|
+
RwMsgHandler *handler = basehandler->handler;
|
|
756
|
+
while(handler){
|
|
757
|
+
int state = 0;
|
|
758
|
+
VALUE args[3];
|
|
759
|
+
args[0] = handler->receiver;
|
|
760
|
+
args[1] = handler->handler_id;
|
|
761
|
+
if (handler->arg_template) {
|
|
762
|
+
VALUE v_cv = Qfalse;
|
|
763
|
+
switch(handler->arg_template[0]){
|
|
764
|
+
case 'i':
|
|
765
|
+
args[2] = ULONG_PTR2NUM((ULONG_PTR)hdc);
|
|
766
|
+
break;
|
|
767
|
+
case 'c':
|
|
768
|
+
v_cv = rwcvs_new_from_hdc(handler->klass, hdc);
|
|
769
|
+
args[2] = v_cv;
|
|
770
|
+
break;
|
|
771
|
+
default:
|
|
772
|
+
rb_bug("Unkown template: `%c' for WM_PAINT", handler->arg_template[0]);
|
|
773
|
+
}
|
|
774
|
+
rb_protect(rw_funcall_1, (VALUE)args, &state);
|
|
775
|
+
#if !USE_RGENGC
|
|
776
|
+
if(v_gr) rb_gc_force_recycle(v_gr);
|
|
777
|
+
#endif
|
|
778
|
+
} else {
|
|
779
|
+
rb_protect(rw_funcall_0, (VALUE)args, &state);
|
|
780
|
+
}
|
|
781
|
+
if (state) rw_abort_program(state);
|
|
782
|
+
handler = handler->next;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
static int
|
|
787
|
+
setwparam2args(WPARAM wParam, char* template, VALUE* nargs, VALUE* args){
|
|
788
|
+
if(!*template) return 0;
|
|
789
|
+
switch(*template){
|
|
790
|
+
case 'h': /* arg is [(signed)LOWORD, (signed)HIWORD]*/
|
|
791
|
+
*nargs += 2;
|
|
792
|
+
args[0] = INT2FIX((short)LOWORD(wParam));
|
|
793
|
+
args[1] = INT2FIX((short)HIWORD(wParam));
|
|
794
|
+
return 2;
|
|
795
|
+
case 'i': /* arg is INT */
|
|
796
|
+
*nargs += 1;
|
|
797
|
+
*args = ULONG_PTR2NUM(wParam);
|
|
798
|
+
return 1;
|
|
799
|
+
case 'x': /* skip */
|
|
800
|
+
return 0;
|
|
801
|
+
default:
|
|
802
|
+
rb_bug("unknown template: `%c' for wParam", *template);
|
|
803
|
+
return 0;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
static int
|
|
808
|
+
setlparam2args(LPARAM lParam, char* template, VALUE* nargs, VALUE* args){
|
|
809
|
+
if(!*template) return 0;
|
|
810
|
+
switch(*template){
|
|
811
|
+
case 'h': /* arg is [(signed)LOWORD, (signed)HIWORD]*/
|
|
812
|
+
*nargs += 2;
|
|
813
|
+
args[0] = INT2FIX((short)LOWORD(lParam));
|
|
814
|
+
args[1] = INT2FIX((short)HIWORD(lParam));
|
|
815
|
+
return 2;
|
|
816
|
+
case 'i': /* arg is INT */
|
|
817
|
+
*nargs += 1;
|
|
818
|
+
*args = LONG_PTR2NUM(lParam);
|
|
819
|
+
return 1;
|
|
820
|
+
case 's': /* arg is CStruct */
|
|
821
|
+
*nargs += 1;
|
|
822
|
+
return -1;
|
|
823
|
+
case 'x': /* skip */
|
|
824
|
+
return 0;
|
|
825
|
+
default:
|
|
826
|
+
rb_bug("unknown template: `%c' for lParam", *template);
|
|
827
|
+
return 0;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
static RwMsgHandler*
|
|
832
|
+
rw_translate_msg(VALUE callto, RwBaseHandler *basehandler, UINT msg, WPARAM *wParam, LPARAM *lParam){
|
|
833
|
+
VALUE retval = Qnil;
|
|
834
|
+
VALUE args[4];
|
|
835
|
+
RwMsgHandler *handler = basehandler->handler;
|
|
836
|
+
if(basehandler->senders){
|
|
837
|
+
int state;
|
|
838
|
+
unsigned idfrom, subfilter;
|
|
839
|
+
AAnode *node, *subnode;
|
|
840
|
+
RwMsgHandler *subhandler = NULL;
|
|
841
|
+
ID callback_id = handler->handler_id;
|
|
842
|
+
if (!callback_id){
|
|
843
|
+
switch(msg){
|
|
844
|
+
case WM_COMMAND:
|
|
845
|
+
case WM_TIMER:
|
|
846
|
+
idfrom = LOWORD(*wParam);
|
|
847
|
+
if(*lParam){ /* from controls */
|
|
848
|
+
subfilter = HIWORD(*wParam);
|
|
849
|
+
} else { /* from menu */
|
|
850
|
+
subfilter = HIWORD(*wParam) & 0xfffe; /* mask LSB */
|
|
851
|
+
}
|
|
852
|
+
node = aaSearch(basehandler->senders, idfrom);
|
|
853
|
+
if(node){
|
|
854
|
+
subnode = aaSearch((AAtree*)(node->val), subfilter);
|
|
855
|
+
if (subnode) subhandler = subnode->val;
|
|
856
|
+
}
|
|
857
|
+
return subhandler;
|
|
858
|
+
case WM_NOTIFY:
|
|
859
|
+
idfrom = ((NMHDR*)*lParam)->idFrom;
|
|
860
|
+
subfilter = ((NMHDR*)*lParam)->code;
|
|
861
|
+
node = aaSearch(basehandler->senders, idfrom);
|
|
862
|
+
if(node){
|
|
863
|
+
subnode = aaSearch((AAtree*)(node->val), subfilter);
|
|
864
|
+
if (subnode) subhandler = subnode->val;
|
|
865
|
+
}
|
|
866
|
+
return subhandler;
|
|
867
|
+
}
|
|
868
|
+
} else {
|
|
869
|
+
char *template = handler->arg_template;
|
|
870
|
+
args[0] = callto;
|
|
871
|
+
args[1] = callback_id;
|
|
872
|
+
args[2] = 0;
|
|
873
|
+
if (template){
|
|
874
|
+
int n = setwparam2args(*wParam, template, &args[2], &args[3]);
|
|
875
|
+
n = setlparam2args(*lParam, ++template, &args[2], &args[3+n]);
|
|
876
|
+
}
|
|
877
|
+
retval = rb_protect(rw_funcall_n, (VALUE)args, &state);
|
|
878
|
+
if (state) rw_abort_program(state);
|
|
879
|
+
if (TYPE(retval) == T_ARRAY){
|
|
880
|
+
VALUE v_idfrom, v_subfilter, v_wParam, v_lParam;
|
|
881
|
+
if (NIL_P(v_idfrom = rb_ary_entry(retval, 0))) return NULL;
|
|
882
|
+
idfrom = FIX2INT(v_idfrom);
|
|
883
|
+
if (NIL_P(v_subfilter = rb_ary_entry(retval, 1))) return NULL;
|
|
884
|
+
subfilter = FIX2INT(v_subfilter);
|
|
885
|
+
if (! NIL_P(v_wParam = rb_ary_entry(retval, 2))) *wParam = NUM2INT(v_wParam);
|
|
886
|
+
if (! NIL_P(v_lParam = rb_ary_entry(retval, 3))) *lParam = NUM2INT(v_lParam);
|
|
887
|
+
node = aaSearch(basehandler->senders, idfrom);
|
|
888
|
+
if(node){
|
|
889
|
+
subnode = aaSearch((AAtree*)(node->val), subfilter);
|
|
890
|
+
if (subnode) subhandler = subnode->val;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
return subhandler;
|
|
895
|
+
}
|
|
896
|
+
return handler;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
static int
|
|
900
|
+
dispatch_handler(VALUE wobj, RwBaseHandler *basehandler, UINT msg, WPARAM wParam, LPARAM lParam){
|
|
901
|
+
VALUE ret = Qnil;
|
|
902
|
+
RwMsgHandler *handler = rw_translate_msg(wobj, basehandler, msg, &wParam, &lParam);
|
|
903
|
+
while (handler){
|
|
904
|
+
int n = 0;
|
|
905
|
+
int is_struct = 0;
|
|
906
|
+
int state = 0;
|
|
907
|
+
VALUE args[8];
|
|
908
|
+
char *template = handler->arg_template;
|
|
909
|
+
args[0] = handler->receiver;
|
|
910
|
+
args[1] = handler->handler_id;
|
|
911
|
+
args[2] = 0;
|
|
912
|
+
if (template){
|
|
913
|
+
n = setwparam2args(wParam, template, &args[2], &args[3]);
|
|
914
|
+
is_struct = setlparam2args(lParam, ++template, &args[2], &args[3+n]);
|
|
915
|
+
}
|
|
916
|
+
if (is_struct==-1){ /* lParam to CStruct */
|
|
917
|
+
VALUE obj;
|
|
918
|
+
if (handler->klass==Qnil) rb_raise(rb_eRuntimeError, "No CStruct given");
|
|
919
|
+
obj = cstruct_wrapptr(handler->klass, (char*)lParam, 0);
|
|
920
|
+
args[3+n] = obj;
|
|
921
|
+
ret = rb_protect(rw_funcall_n, (VALUE)args, &state);
|
|
922
|
+
#if !USE_RGENGC
|
|
923
|
+
rb_gc_force_recycle(obj);
|
|
924
|
+
#endif
|
|
925
|
+
} else {
|
|
926
|
+
ret = rb_protect(rw_funcall_n, (VALUE)args, &state);
|
|
927
|
+
}
|
|
928
|
+
if (state) rw_abort_program(state);
|
|
929
|
+
if (ret == cRwCancelDefWndProc){
|
|
930
|
+
return 1;
|
|
931
|
+
} else if (rb_typeddata_is_kind_of(ret, &rw_candefwndprc_d_type)){
|
|
932
|
+
RwCancelDefWindowProc *rcp;
|
|
933
|
+
TypedData_Get_Struct(ret, RwCancelDefWindowProc, &rw_candefwndprc_d_type, rcp);
|
|
934
|
+
if (rcp->retval){
|
|
935
|
+
return rcp->retval;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
handler = handler->next;
|
|
939
|
+
}
|
|
940
|
+
return 0;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
LRESULT
|
|
944
|
+
do_wm_default(VALUE wobj, UINT *msg, WPARAM *wParam, LPARAM *lParam){
|
|
945
|
+
RwWindow *rw = DATA_PTR(wobj);
|
|
946
|
+
LRESULT r = 0;
|
|
947
|
+
if(rw->msgfilter){
|
|
948
|
+
AAnode *node = aaSearch(rw->msgfilter, *msg);
|
|
949
|
+
if (node){
|
|
950
|
+
RwBaseHandler *basehandler = node->val;
|
|
951
|
+
if(basehandler){
|
|
952
|
+
r = dispatch_handler(wobj, basehandler, *msg, *wParam, *lParam);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return r;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
//void
|
|
960
|
+
//aa_callback_test(const AAnode *node, void *arg){
|
|
961
|
+
// fprintf(stderr, "[key=%#x, val=%#x], ", (int)node->key, (int)node->val);
|
|
962
|
+
//}
|
|
963
|
+
|
|
964
|
+
static void
|
|
965
|
+
aa_callback_finalize_resoure(const AAnode *node, void *arg){
|
|
966
|
+
VALUE obj = (VALUE)node->val;
|
|
967
|
+
if(rb_typeddata_is_kind_of(obj, &rwimage_data_type)){
|
|
968
|
+
RwImage *rp;
|
|
969
|
+
RwImage_Data_Get_Struct(obj, rp);
|
|
970
|
+
if(rp->himage) GdipDisposeImage(rp->himage);
|
|
971
|
+
rp->himage = 0;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
static void
|
|
976
|
+
rwwin_finalize(){
|
|
977
|
+
aaForeach(rsclist, aa_callback_finalize_resoure, NULL);
|
|
978
|
+
rwgdiplus_shutdown();
|
|
979
|
+
// PostQuitMessage(0);
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
LRESULT CALLBACK
|
|
984
|
+
RwWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
|
985
|
+
if(GetClassLong(hWnd, GCW_ATOM)==RwClassAtom){
|
|
986
|
+
VALUE wobj = Get_win(hWnd);
|
|
987
|
+
if(wobj){
|
|
988
|
+
RwWindow *rw = DATA_PTR(wobj);
|
|
989
|
+
if (uMsg==WM_PAINT){
|
|
990
|
+
if (rw->msgfilter) {
|
|
991
|
+
AAnode *nd = aaSearch(rw->msgfilter, WM_PAINT);
|
|
992
|
+
if (nd) {
|
|
993
|
+
PAINTSTRUCT ps;
|
|
994
|
+
RwBaseHandler *basehandler = nd->val;
|
|
995
|
+
HDC hdc = BeginPaint(rw->hwnd, &ps);
|
|
996
|
+
dispatch_wm_paint_handler(wobj, basehandler, hdc);
|
|
997
|
+
EndPaint(rw->hwnd, &ps);
|
|
998
|
+
return 0;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
1002
|
+
} else {
|
|
1003
|
+
LRESULT ret;
|
|
1004
|
+
if (uMsg==WM_ACTIVATE) activewin = LOWORD(wParam) ? DATA_PTR(wobj) : NULL;
|
|
1005
|
+
ret=do_wm_default(wobj, &uMsg, &wParam, &lParam);
|
|
1006
|
+
if (ret){
|
|
1007
|
+
return ret;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
switch (uMsg) {
|
|
1012
|
+
case WM_CREATE:
|
|
1013
|
+
return 0;
|
|
1014
|
+
case WM_CLOSE:
|
|
1015
|
+
DestroyWindow(hWnd);
|
|
1016
|
+
break;
|
|
1017
|
+
case WM_DESTROY:
|
|
1018
|
+
if(wobj){
|
|
1019
|
+
RwWindow *rw = (RwWindow*)DATA_PTR(wobj);
|
|
1020
|
+
if(!GetParent(hWnd)) {
|
|
1021
|
+
Unregister_win(hWnd);
|
|
1022
|
+
if(aaCount(winlist)==0) {
|
|
1023
|
+
rwwin_finalize();
|
|
1024
|
+
PostQuitMessage(wParam);
|
|
1025
|
+
return 0;
|
|
1026
|
+
}
|
|
1027
|
+
} else {
|
|
1028
|
+
Unregister_childwin(hWnd);
|
|
1029
|
+
}
|
|
1030
|
+
rw->hwnd = NULL;
|
|
1031
|
+
}
|
|
1032
|
+
return 0;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
LRESULT CALLBACK RwSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData){
|
|
1039
|
+
VALUE wobj = (VALUE)dwRefData;
|
|
1040
|
+
RwWindow *rw = (RwWindow*)DATA_PTR(wobj);
|
|
1041
|
+
if (uMsg==WM_PAINT){
|
|
1042
|
+
if (rw->msgfilter) {
|
|
1043
|
+
AAnode *nd = aaSearch(rw->msgfilter, WM_PAINT);
|
|
1044
|
+
if (nd) {
|
|
1045
|
+
PAINTSTRUCT ps;
|
|
1046
|
+
RwBaseHandler *basehandler = nd->val;
|
|
1047
|
+
HDC hdc = BeginPaint(rw->hwnd, &ps);
|
|
1048
|
+
dispatch_wm_paint_handler(wobj, basehandler, hdc);
|
|
1049
|
+
EndPaint(rw->hwnd, &ps);
|
|
1050
|
+
return 0;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
} else {
|
|
1054
|
+
LONG_PTR ret = do_wm_default(wobj, &uMsg, &wParam, &lParam);
|
|
1055
|
+
if (ret) return ret; /* cancel default wndproc */
|
|
1056
|
+
if(uMsg==WM_DESTROY){
|
|
1057
|
+
Unregister_childwin(hWnd);
|
|
1058
|
+
rw->hwnd = NULL;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
static VALUE
|
|
1065
|
+
rwwin_close(VALUE self){
|
|
1066
|
+
int r; //AAnode *nd;
|
|
1067
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1068
|
+
RwCheckWindow(rw);
|
|
1069
|
+
r = DestroyWindow(rw->hwnd);
|
|
1070
|
+
if(rw->hwnd){ /* for child windows (Not received WM_DESTROY) */
|
|
1071
|
+
Unregister_childwin(rw->hwnd);
|
|
1072
|
+
rw->hwnd = NULL;
|
|
1073
|
+
}
|
|
1074
|
+
return r ? Qtrue : Qfalse;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
static VALUE
|
|
1078
|
+
rwwin_gethandle(VALUE self){
|
|
1079
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1080
|
+
RwCheckWindow(rw);
|
|
1081
|
+
return ULONG_PTR2NUM((ULONG_PTR)rw->hwnd);
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
static VALUE
|
|
1085
|
+
rwwin_alive_p(VALUE self){
|
|
1086
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1087
|
+
return rw->hwnd ? Qtrue : Qfalse;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/*
|
|
1091
|
+
static void
|
|
1092
|
+
rw_move_core(HWND hwnd, POINT *pt){
|
|
1093
|
+
HWND hparent;
|
|
1094
|
+
if(hparent=GetParent(hwnd)) ClientToScreen(hparent, pt);
|
|
1095
|
+
}*/
|
|
1096
|
+
|
|
1097
|
+
static VALUE
|
|
1098
|
+
rwwin_move(int argc, VALUE * argv, VALUE self){
|
|
1099
|
+
RECT rc;
|
|
1100
|
+
int x, y, w, h;
|
|
1101
|
+
BOOL brepaint = TRUE;
|
|
1102
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1103
|
+
RwCheckWindow(rw);
|
|
1104
|
+
switch(argc){
|
|
1105
|
+
case 5:
|
|
1106
|
+
if(argv[4]==Qfalse) brepaint = FALSE;
|
|
1107
|
+
case 4:
|
|
1108
|
+
x = FIX2INT(argv[0]);
|
|
1109
|
+
y = FIX2INT(argv[1]);
|
|
1110
|
+
w = FIX2INT(argv[2]);
|
|
1111
|
+
h = FIX2INT(argv[3]);
|
|
1112
|
+
break;
|
|
1113
|
+
case 3:
|
|
1114
|
+
if(argv[2]==Qfalse) brepaint = FALSE;
|
|
1115
|
+
case 2:
|
|
1116
|
+
x = FIX2INT(argv[0]);
|
|
1117
|
+
y = FIX2INT(argv[1]);
|
|
1118
|
+
GetWindowRect(rw->hwnd, &rc);
|
|
1119
|
+
w = rc.right - rc.left;
|
|
1120
|
+
h = rc.bottom - rc.top;
|
|
1121
|
+
break;
|
|
1122
|
+
default:
|
|
1123
|
+
rb_raise(rb_eArgError, "Num of arguments must be 2..5");
|
|
1124
|
+
}
|
|
1125
|
+
rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd, x, y, w, h, brepaint);
|
|
1126
|
+
return self;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
static VALUE
|
|
1130
|
+
rwwin_resize(VALUE self, VALUE v_w, VALUE v_h){
|
|
1131
|
+
RECT rc;
|
|
1132
|
+
POINT pos;
|
|
1133
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1134
|
+
RwCheckWindow(rw);
|
|
1135
|
+
GetWindowRect(rw->hwnd, &rc);
|
|
1136
|
+
pos.x = rc.left;
|
|
1137
|
+
pos.y = rc.top;
|
|
1138
|
+
ScreenToClient(GetAncestor(rw->hwnd, GA_PARENT), &pos);
|
|
1139
|
+
rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
|
|
1140
|
+
pos.x, pos.y, FIX2INT(v_w), FIX2INT(v_h), TRUE);
|
|
1141
|
+
return self;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
static VALUE
|
|
1145
|
+
rwwin_refresh(int argc, VALUE *argv, VALUE self){
|
|
1146
|
+
RECT rect;
|
|
1147
|
+
RECT *prect;
|
|
1148
|
+
BOOL bErase;
|
|
1149
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1150
|
+
RwCheckWindow(rw);
|
|
1151
|
+
if(argc<=1){
|
|
1152
|
+
prect = NULL;
|
|
1153
|
+
bErase = (argc==1 && argv[0]==Qfalse) ? FALSE : TRUE;
|
|
1154
|
+
} else if(argc<=5){
|
|
1155
|
+
rect.left = FIX2INT(argv[0]);
|
|
1156
|
+
rect.top = FIX2INT(argv[1]);
|
|
1157
|
+
rect.right = rect.left + FIX2INT(argv[2]);
|
|
1158
|
+
rect.bottom = rect.top + FIX2INT(argv[3]);
|
|
1159
|
+
prect = ▭
|
|
1160
|
+
bErase = (argc==5 && argv[4]==Qfalse) ? FALSE : TRUE;
|
|
1161
|
+
} else{
|
|
1162
|
+
rb_raise(rb_eArgError, "invalid num of args: %d", argc);
|
|
1163
|
+
}
|
|
1164
|
+
InvalidateRect(rw->hwnd, prect, bErase);
|
|
1165
|
+
return self;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
static void
|
|
1169
|
+
rw_getclientpos_core(HWND hwnd, RECT *rc){
|
|
1170
|
+
HWND hparent;
|
|
1171
|
+
GetWindowRect(hwnd, rc);
|
|
1172
|
+
if(hparent=GetAncestor(hwnd, GA_PARENT)) ScreenToClient(hparent, (POINT*)rc);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
static VALUE
|
|
1176
|
+
rwwin_getscreenpos(VALUE self){
|
|
1177
|
+
RECT rc;
|
|
1178
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1179
|
+
RwCheckWindow(rw);
|
|
1180
|
+
GetWindowRect(rw->hwnd, &rc);
|
|
1181
|
+
return rb_ary_new3(2, INT2FIX(rc.left), INT2FIX(rc.top));
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
static VALUE
|
|
1185
|
+
rwwin_getclientpos(VALUE self){
|
|
1186
|
+
RECT rc;
|
|
1187
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1188
|
+
RwCheckWindow(rw);
|
|
1189
|
+
rw_getclientpos_core(rw->hwnd, &rc);
|
|
1190
|
+
return rb_ary_new3(2, INT2FIX(rc.left), INT2FIX(rc.top));
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
static VALUE
|
|
1194
|
+
rwwin_getwndsize(VALUE self){
|
|
1195
|
+
RECT rc;
|
|
1196
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1197
|
+
RwCheckWindow(rw);
|
|
1198
|
+
GetWindowRect(rw->hwnd, &rc);
|
|
1199
|
+
return rb_ary_new3(2, INT2FIX(rc.right - rc.left), INT2FIX(rc.bottom - rc.top));
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
static VALUE
|
|
1203
|
+
rwwin_getclientsize(VALUE self){
|
|
1204
|
+
RECT rc;
|
|
1205
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1206
|
+
RwCheckWindow(rw);
|
|
1207
|
+
GetClientRect(rw->hwnd, &rc);
|
|
1208
|
+
return rb_ary_new3(2, INT2FIX(rc.right), INT2FIX(rc.bottom));
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
static VALUE
|
|
1212
|
+
rwwin_setorder(VALUE self, VALUE v_wndafter){
|
|
1213
|
+
RwWindow *rwafter;
|
|
1214
|
+
HWND hwndafter;
|
|
1215
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1216
|
+
RwCheckWindow(rw);
|
|
1217
|
+
switch(TYPE(v_wndafter)){
|
|
1218
|
+
case T_FIXNUM:
|
|
1219
|
+
case T_BIGNUM:
|
|
1220
|
+
hwndafter = (HWND)NUM2ULONG_PTR(v_wndafter);
|
|
1221
|
+
break;
|
|
1222
|
+
default:
|
|
1223
|
+
RwWindow_Data_Get_Struct(v_wndafter, rwafter);
|
|
1224
|
+
hwndafter = rwafter->hwnd;
|
|
1225
|
+
}
|
|
1226
|
+
SetWindowPos(rw->hwnd, hwndafter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
1227
|
+
return self;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
static VALUE
|
|
1231
|
+
rwwin_getcursorpos(VALUE self){
|
|
1232
|
+
VALUE robj;
|
|
1233
|
+
POINT pt;
|
|
1234
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1235
|
+
GetCursorPos(&pt);
|
|
1236
|
+
ScreenToClient(rw->hwnd, &pt);
|
|
1237
|
+
robj = rb_ary_new2(2);
|
|
1238
|
+
rb_ary_store(robj, 0, INT2NUM(pt.x));
|
|
1239
|
+
rb_ary_store(robj, 1, INT2NUM(pt.y));
|
|
1240
|
+
return robj;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/* r/w attributes */
|
|
1244
|
+
static VALUE
|
|
1245
|
+
rwwin_getcaption(VALUE self){
|
|
1246
|
+
int len;
|
|
1247
|
+
TCHAR *buff;
|
|
1248
|
+
VALUE robj;
|
|
1249
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1250
|
+
RwCheckWindow(rw);
|
|
1251
|
+
len = GetWindowTextLength(rw->hwnd);
|
|
1252
|
+
buff = malloc((len+1)*sizeof(TCHAR));
|
|
1253
|
+
GetWindowText(rw->hwnd, buff, len+1);
|
|
1254
|
+
robj = rw_encode_external(buff);
|
|
1255
|
+
free(buff);
|
|
1256
|
+
return robj;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
static VALUE
|
|
1260
|
+
rwwin_setcaption(VALUE self, VALUE str){
|
|
1261
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1262
|
+
RwCheckWindow(rw);
|
|
1263
|
+
rw_call_without_gvl_2(rw->nthread_id, (FARPROC)SetWindowText, (ULONG_PTR)rw->hwnd,
|
|
1264
|
+
(ULONG_PTR)rw_str2tchar(StringValue(str)));
|
|
1265
|
+
return self;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
static VALUE
|
|
1269
|
+
rwwin_getvisible(VALUE self){
|
|
1270
|
+
int r;
|
|
1271
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1272
|
+
RwCheckWindow(rw);
|
|
1273
|
+
r = rw_call_without_gvl_1(rw->nthread_id, (FARPROC)IsWindowVisible, (ULONG_PTR)rw->hwnd);
|
|
1274
|
+
return r ? Qtrue : Qnil;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
static VALUE
|
|
1278
|
+
rwwin_setvisible(VALUE self, VALUE v_flag){
|
|
1279
|
+
int swvisible;
|
|
1280
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1281
|
+
RwCheckWindow(rw);
|
|
1282
|
+
switch(TYPE(v_flag)){
|
|
1283
|
+
case T_TRUE:
|
|
1284
|
+
swvisible = SW_SHOW;
|
|
1285
|
+
break;
|
|
1286
|
+
case T_FALSE:
|
|
1287
|
+
swvisible = SW_HIDE;
|
|
1288
|
+
break;
|
|
1289
|
+
case T_FIXNUM:
|
|
1290
|
+
case T_BIGNUM:
|
|
1291
|
+
swvisible = FIX2INT(v_flag);
|
|
1292
|
+
break;
|
|
1293
|
+
default:
|
|
1294
|
+
rb_raise(rb_eTypeError, "Argument must be true or false or Integer");
|
|
1295
|
+
}
|
|
1296
|
+
rw_call_without_gvl_2(rw->nthread_id, (FARPROC)ShowWindow, (ULONG_PTR)rw->hwnd, swvisible);
|
|
1297
|
+
return self;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
static VALUE
|
|
1301
|
+
rwwin_getidcmd(VALUE self){
|
|
1302
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1303
|
+
RwCheckWindow(rw);
|
|
1304
|
+
return INT2FIX(GetWindowLongPtr(rw->hwnd, GWLP_ID));
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
static VALUE
|
|
1308
|
+
rwwin_setidcmd(VALUE self, VALUE v_id){
|
|
1309
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1310
|
+
RwCheckWindow(rw);
|
|
1311
|
+
SetWindowLongPtr(rw->hwnd, GWLP_ID, FIX2INT(v_id));
|
|
1312
|
+
return self;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
static VALUE
|
|
1316
|
+
rwwin_getparent(VALUE self){
|
|
1317
|
+
HWND hparent;
|
|
1318
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1319
|
+
RwCheckWindow(rw);
|
|
1320
|
+
if(hparent = GetParent(rw->hwnd)){
|
|
1321
|
+
VALUE pw;
|
|
1322
|
+
if(!(pw = Get_win(hparent))) pw = Get_childwin(hparent);
|
|
1323
|
+
return pw ? pw : Qnil;
|
|
1324
|
+
}
|
|
1325
|
+
return Qnil;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
static VALUE
|
|
1329
|
+
rwwin_setparent(VALUE self, VALUE v_parent){
|
|
1330
|
+
HWND h_old;
|
|
1331
|
+
RwWindow *rp;
|
|
1332
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1333
|
+
RwCheckWindow(rw);
|
|
1334
|
+
RwWindow_Data_Get_Struct(v_parent, rp);
|
|
1335
|
+
RwCheckWindow(rp);
|
|
1336
|
+
h_old = SetParent(rw->hwnd, rp->hwnd);
|
|
1337
|
+
if(h_old){
|
|
1338
|
+
VALUE pw;
|
|
1339
|
+
if(!(pw = Get_win(h_old))) pw = Get_childwin(h_old);
|
|
1340
|
+
return pw ? pw : Qnil;
|
|
1341
|
+
}else{
|
|
1342
|
+
return Qnil;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
static VALUE
|
|
1347
|
+
rwwin_getx(VALUE self){
|
|
1348
|
+
RECT rc;
|
|
1349
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1350
|
+
RwCheckWindow(rw);
|
|
1351
|
+
rw_getclientpos_core(rw->hwnd, &rc);
|
|
1352
|
+
return INT2FIX(rc.left);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
static VALUE
|
|
1356
|
+
rwwin_gety(VALUE self){
|
|
1357
|
+
RECT rc;
|
|
1358
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1359
|
+
RwCheckWindow(rw);
|
|
1360
|
+
rw_getclientpos_core(rw->hwnd, &rc);
|
|
1361
|
+
return INT2FIX(rc.top);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
static VALUE
|
|
1365
|
+
rwwin_getw(VALUE self){
|
|
1366
|
+
RECT rc;
|
|
1367
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1368
|
+
RwCheckWindow(rw);
|
|
1369
|
+
GetWindowRect(rw->hwnd, &rc);
|
|
1370
|
+
return INT2FIX(rc.right - rc.left);
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
static VALUE
|
|
1374
|
+
rwwin_geth(VALUE self){
|
|
1375
|
+
RECT rc;
|
|
1376
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1377
|
+
RwCheckWindow(rw);
|
|
1378
|
+
GetWindowRect(rw->hwnd, &rc);
|
|
1379
|
+
return INT2FIX(rc.bottom - rc.top);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
static void
|
|
1383
|
+
rw_setxy_core(HWND hwnd, POINT *pt, int *w, int *h){
|
|
1384
|
+
RECT rc;
|
|
1385
|
+
GetWindowRect(hwnd, &rc);
|
|
1386
|
+
*w = rc.right - rc.left;
|
|
1387
|
+
*h = rc.bottom - rc.top;
|
|
1388
|
+
pt->x = rc.left;
|
|
1389
|
+
pt->y = rc.top;
|
|
1390
|
+
ScreenToClient(GetAncestor(hwnd, GA_PARENT), pt);
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
static VALUE
|
|
1394
|
+
rwwin_setx(VALUE self, VALUE v_x){
|
|
1395
|
+
int w, h;
|
|
1396
|
+
POINT pt;
|
|
1397
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1398
|
+
RwCheckWindow(rw);
|
|
1399
|
+
rw_setxy_core(rw->hwnd, &pt, &w, &h);
|
|
1400
|
+
rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
|
|
1401
|
+
FIX2INT(v_x), pt.y, w, h, FALSE);
|
|
1402
|
+
return v_x;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
static VALUE
|
|
1406
|
+
rwwin_sety(VALUE self, VALUE v_y){
|
|
1407
|
+
int w, h;
|
|
1408
|
+
POINT pt;
|
|
1409
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1410
|
+
RwCheckWindow(rw);
|
|
1411
|
+
rw_setxy_core(rw->hwnd, &pt, &w, &h);
|
|
1412
|
+
rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
|
|
1413
|
+
pt.x, FIX2INT(v_y), w, h, FALSE);
|
|
1414
|
+
return v_y;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
static VALUE
|
|
1418
|
+
rwwin_setw(VALUE self, VALUE v_w){
|
|
1419
|
+
int w, h;
|
|
1420
|
+
POINT pt;
|
|
1421
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1422
|
+
RwCheckWindow(rw);
|
|
1423
|
+
rw_setxy_core(rw->hwnd, &pt, &w, &h);
|
|
1424
|
+
rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
|
|
1425
|
+
pt.x, pt.y, FIX2INT(v_w), h, FALSE);
|
|
1426
|
+
return v_w;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
static VALUE
|
|
1430
|
+
rwwin_seth(VALUE self, VALUE v_h){
|
|
1431
|
+
int w, h;
|
|
1432
|
+
POINT pt;
|
|
1433
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1434
|
+
RwCheckWindow(rw);
|
|
1435
|
+
rw_setxy_core(rw->hwnd, &pt, &w, &h);
|
|
1436
|
+
rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
|
|
1437
|
+
pt.x, pt.y, w, FIX2INT(v_h), FALSE);
|
|
1438
|
+
return v_h;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
static VALUE
|
|
1442
|
+
rwwin_setsubclass(VALUE self){
|
|
1443
|
+
int id;
|
|
1444
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1445
|
+
RwCheckWindow(rw);
|
|
1446
|
+
id = GetWindowLongPtr(rw->hwnd, GWLP_ID);
|
|
1447
|
+
SetWindowSubclass(rw->hwnd, RwSubclassProc, (UINT_PTR)id, (DWORD_PTR)self);
|
|
1448
|
+
return self;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
static VALUE
|
|
1452
|
+
rwwin_removesubclass(VALUE self){
|
|
1453
|
+
int id;
|
|
1454
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1455
|
+
RwCheckWindow(rw);
|
|
1456
|
+
id = GetWindowLongPtr(rw->hwnd, GWLP_ID);
|
|
1457
|
+
RemoveWindowSubclass(rw->hwnd, RwSubclassProc, (UINT_PTR)id);
|
|
1458
|
+
return self;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
static ULONG_PTR
|
|
1462
|
+
rw_get_param(VALUE v_param){
|
|
1463
|
+
switch(TYPE(v_param)) {
|
|
1464
|
+
case T_FIXNUM:
|
|
1465
|
+
case T_BIGNUM:
|
|
1466
|
+
return NUM2ULONG_PTR(v_param);
|
|
1467
|
+
case T_DATA:
|
|
1468
|
+
if (rb_typeddata_is_kind_of(v_param, &cstruct_data_type)){
|
|
1469
|
+
CStructData *cs;
|
|
1470
|
+
CStruct_Data_Get_Struct(v_param, cs);
|
|
1471
|
+
return (ULONG_PTR)cs->dtstr + cs->dtoffset;
|
|
1472
|
+
}
|
|
1473
|
+
case T_STRING:
|
|
1474
|
+
if(rb_enc_get_index(v_param)) {
|
|
1475
|
+
return (ULONG_PTR)rw_str2tchar(v_param);
|
|
1476
|
+
} else {
|
|
1477
|
+
return (ULONG_PTR)RSTRING_PTR(v_param);
|
|
1478
|
+
}
|
|
1479
|
+
default:
|
|
1480
|
+
rb_raise(rb_eTypeError, "Invalid type:%s", rb_class2name(rb_class_of(v_param)));
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
static VALUE
|
|
1485
|
+
rwwin_setfocus(VALUE self){
|
|
1486
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1487
|
+
RwCheckWindow(rw);
|
|
1488
|
+
return SetFocus(rw->hwnd) ? self : Qnil;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
static VALUE
|
|
1492
|
+
rwwin_setredraw(int argc, VALUE *argv, VALUE self){
|
|
1493
|
+
VALUE v_flag ;//, v_l, v_t, v_r, v_b;
|
|
1494
|
+
int flag;
|
|
1495
|
+
RECT rc;
|
|
1496
|
+
RECT *prc = NULL;
|
|
1497
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1498
|
+
switch(argc){
|
|
1499
|
+
case 0:
|
|
1500
|
+
flag = RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN;
|
|
1501
|
+
break;
|
|
1502
|
+
case 1:
|
|
1503
|
+
v_flag = argv[0];
|
|
1504
|
+
if (!v_flag) {
|
|
1505
|
+
flag = FALSE;
|
|
1506
|
+
} else {
|
|
1507
|
+
flag = (v_flag==Qtrue) ? RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN :\
|
|
1508
|
+
FIX2INT(v_flag);
|
|
1509
|
+
}
|
|
1510
|
+
break;
|
|
1511
|
+
case 4:
|
|
1512
|
+
rc.left = FIX2INT(argv[0]);
|
|
1513
|
+
rc.top = FIX2INT(argv[1]);
|
|
1514
|
+
rc.right = FIX2INT(argv[2]);
|
|
1515
|
+
rc.bottom = FIX2INT(argv[3]);
|
|
1516
|
+
prc = &rc;
|
|
1517
|
+
flag = RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN;
|
|
1518
|
+
break;
|
|
1519
|
+
case 5:
|
|
1520
|
+
rc.left = FIX2INT(argv[0]);
|
|
1521
|
+
rc.top = FIX2INT(argv[1]);
|
|
1522
|
+
rc.right = FIX2INT(argv[2]);
|
|
1523
|
+
rc.bottom = FIX2INT(argv[3]);
|
|
1524
|
+
prc = &rc;
|
|
1525
|
+
flag = (argv[4]==Qtrue) ? RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN :\
|
|
1526
|
+
FIX2INT(argv[4]);
|
|
1527
|
+
break;
|
|
1528
|
+
default:
|
|
1529
|
+
rb_raise(rb_eArgError, "Num of arguments must be 0, 1, 4 or 5");
|
|
1530
|
+
}
|
|
1531
|
+
SendMessage(rw->hwnd, WM_SETREDRAW, flag, 0);
|
|
1532
|
+
if(flag) RedrawWindow(rw->hwnd, prc, NULL, flag);
|
|
1533
|
+
return self;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
static VALUE
|
|
1540
|
+
rwwin_sendmessage(VALUE self, VALUE v_msg, VALUE v_wparam, VALUE v_lparam){
|
|
1541
|
+
int r;
|
|
1542
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1543
|
+
RwCheckWindow(rw);
|
|
1544
|
+
r = rw_call_without_gvl_4(rw->nthread_id, (FARPROC)SendMessage, (ULONG_PTR)rw->hwnd,
|
|
1545
|
+
NUM2UINT(v_msg), rw_get_param(v_wparam), rw_get_param(v_lparam));
|
|
1546
|
+
return INT2NUM(r);
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
static VALUE
|
|
1550
|
+
rwwin_postmessage(VALUE self, VALUE v_msg, VALUE v_wparam, VALUE v_lparam){
|
|
1551
|
+
int r;
|
|
1552
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1553
|
+
RwCheckWindow(rw);
|
|
1554
|
+
r = rw_call_without_gvl_4(rw->nthread_id, (FARPROC)PostMessage, (ULONG_PTR)rw->hwnd,
|
|
1555
|
+
NUM2UINT(v_msg), rw_get_param(v_wparam), rw_get_param(v_lparam));
|
|
1556
|
+
return r ? Qtrue : Qnil;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
static VALUE
|
|
1560
|
+
rwwin_getwndlong(VALUE self, VALUE v_idx){
|
|
1561
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1562
|
+
RwCheckWindow(rw);
|
|
1563
|
+
return INT2NUM(GetWindowLongPtr(rw->hwnd, FIX2INT(v_idx)));
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
static VALUE
|
|
1567
|
+
rwwin_setwndlong(VALUE self, VALUE v_idx, VALUE v_arg){
|
|
1568
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1569
|
+
RwCheckWindow(rw);
|
|
1570
|
+
if (SetWindowLongPtr(rw->hwnd, FIX2INT(v_idx), NUM2INT(v_arg))) {
|
|
1571
|
+
rw_call_without_gvl_7(rw->nthread_id, (FARPROC)SetWindowPos, (ULONG_PTR)rw->hwnd, 0, 0,
|
|
1572
|
+
0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
|
1573
|
+
return Qtrue;
|
|
1574
|
+
}
|
|
1575
|
+
return Qfalse;
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
static VALUE
|
|
1579
|
+
rwwin_setwndpos(VALUE self, VALUE v_insert_after, VALUE v_x, VALUE v_y, VALUE v_w, VALUE v_h, VALUE v_flags){
|
|
1580
|
+
int r, insert_after;
|
|
1581
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1582
|
+
RwCheckWindow(rw);
|
|
1583
|
+
if(rb_typeddata_is_kind_of(v_insert_after, &rwwin_data_type)){
|
|
1584
|
+
RwWindow *wn;
|
|
1585
|
+
RwWindow_Data_Get_Struct(self, wn);
|
|
1586
|
+
RwCheckWindow(wn);
|
|
1587
|
+
insert_after = (ULONG_PTR)wn->hwnd;
|
|
1588
|
+
} else {
|
|
1589
|
+
insert_after = NUM2INT(v_insert_after);
|
|
1590
|
+
}
|
|
1591
|
+
r = rw_call_without_gvl_7(rw->nthread_id, (FARPROC)SetWindowPos, (ULONG_PTR)rw->hwnd,
|
|
1592
|
+
insert_after, FIX2INT(v_x), FIX2INT(v_y), FIX2INT(v_w),
|
|
1593
|
+
FIX2INT(v_h), NUM2INT(v_flags));
|
|
1594
|
+
return r ? Qtrue : Qnil;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
static VALUE
|
|
1598
|
+
rwwin_getwindowrect(VALUE self){
|
|
1599
|
+
RECT rc;
|
|
1600
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1601
|
+
RwCheckWindow(rw);
|
|
1602
|
+
if(GetWindowRect(rw->hwnd, &rc)){
|
|
1603
|
+
CStructData *cs;
|
|
1604
|
+
VALUE v_rect = api_cstruct_new(ccsRECT);
|
|
1605
|
+
CStruct_Data_Get_Struct(v_rect, cs);
|
|
1606
|
+
memcpy(cs->dtstr, &rc, sizeof(RECT)); /* cs->dtoffset is always 0 */
|
|
1607
|
+
return v_rect;
|
|
1608
|
+
} else {
|
|
1609
|
+
return Qfalse;
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
static VALUE
|
|
1614
|
+
rwwin_setcapture(VALUE self){
|
|
1615
|
+
HWND hWnd;
|
|
1616
|
+
VALUE wobj;
|
|
1617
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1618
|
+
RwCheckWindow(rw);
|
|
1619
|
+
hWnd = SetCapture(rw->hwnd);
|
|
1620
|
+
if(!(wobj = Get_win(hWnd))) wobj = Get_childwin(hWnd);
|
|
1621
|
+
return wobj || Qnil; /* return previous captured window */
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
static VALUE
|
|
1625
|
+
rwwin_releasecapture(VALUE self){
|
|
1626
|
+
int r = ReleaseCapture();
|
|
1627
|
+
return r ? Qtrue : Qfalse;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
static VALUE
|
|
1631
|
+
rwwin_showwindow(VALUE self, VALUE v_flag){
|
|
1632
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1633
|
+
RwCheckWindow(rw);
|
|
1634
|
+
rw_call_without_gvl_2(rw->nthread_id, (FARPROC)ShowWindow, (ULONG_PTR)rw->hwnd,
|
|
1635
|
+
FIX2INT(v_flag));
|
|
1636
|
+
return self;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
static VALUE
|
|
1640
|
+
rwwin_registerhotkey(VALUE self, VALUE v_id, VALUE v_modifiers, VALUE v_vkey){
|
|
1641
|
+
int r;
|
|
1642
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1643
|
+
RwCheckWindow(rw);
|
|
1644
|
+
r = RegisterHotKey(rw->hwnd, NUM2INT(v_id), NUM2UINT(v_modifiers), NUM2UINT(v_vkey));
|
|
1645
|
+
return r ? Qtrue : Qfalse;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
static VALUE
|
|
1649
|
+
rwwin_unregisterhotkey(VALUE self, VALUE v_id){
|
|
1650
|
+
int r;
|
|
1651
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1652
|
+
RwCheckWindow(rw);
|
|
1653
|
+
r = UnregisterHotKey(rw->hwnd, NUM2INT(v_id));
|
|
1654
|
+
return r ? Qtrue : Qfalse;
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
static VALUE
|
|
1658
|
+
rwwin_client2screen(VALUE self, VALUE v_x, VALUE v_y){
|
|
1659
|
+
VALUE robj;
|
|
1660
|
+
POINT pt;
|
|
1661
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1662
|
+
pt.x = NUM2INT(v_x);
|
|
1663
|
+
pt.y = NUM2INT(v_y);
|
|
1664
|
+
ClientToScreen(rw->hwnd, &pt);
|
|
1665
|
+
robj = rb_ary_new2(2);
|
|
1666
|
+
rb_ary_store(robj, 0, INT2NUM(pt.x));
|
|
1667
|
+
rb_ary_store(robj, 1, INT2NUM(pt.y));
|
|
1668
|
+
return robj;
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
static VALUE
|
|
1672
|
+
rwwin_screen2client(VALUE self, VALUE v_x, VALUE v_y){
|
|
1673
|
+
VALUE robj;
|
|
1674
|
+
POINT pt;
|
|
1675
|
+
RwWindow *rw = DATA_PTR(self);
|
|
1676
|
+
pt.x = NUM2INT(v_x);
|
|
1677
|
+
pt.y = NUM2INT(v_y);
|
|
1678
|
+
ScreenToClient(rw->hwnd, &pt);
|
|
1679
|
+
robj = rb_ary_new2(2);
|
|
1680
|
+
rb_ary_store(robj, 0, INT2NUM(pt.x));
|
|
1681
|
+
rb_ary_store(robj, 1, INT2NUM(pt.y));
|
|
1682
|
+
return robj;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
void
|
|
1686
|
+
rw_init_RwWindow(){
|
|
1687
|
+
cRwWindow = rb_define_class_under(mRwin, "Window", rb_cData);
|
|
1688
|
+
rb_define_alloc_func(cRwWindow, alloc_rw_window);
|
|
1689
|
+
rb_define_singleton_method(cRwWindow, "new_from_handle", rwwin1_new_from_handle, 1);
|
|
1690
|
+
|
|
1691
|
+
rb_define_method(cRwWindow, "register_event", rwwin_msgfilter_add, -1);
|
|
1692
|
+
rb_define_method(cRwWindow, "unregister_event", rwwin_msgfilter_delete, -1);
|
|
1693
|
+
rb_define_method(cRwWindow, "event_registered?", rwwin_msgfilter_exist_p, -1);
|
|
1694
|
+
rb_define_method(cRwWindow, "registered_messages", rwwin_msgfilter_getfilters, 0);
|
|
1695
|
+
rb_define_method(cRwWindow, "set_msgtranslator", rwwin_msgtranslator_set, -1);
|
|
1696
|
+
rb_define_method(cRwWindow, "get_msgtranslator", rwwin_msgtranslator_get, 1);
|
|
1697
|
+
rb_define_method(cRwWindow, "method_missing", rw_method_missing, -1);
|
|
1698
|
+
rb_define_method(cRwWindow, "set_accelerator", rw_set_accelerator, 1);
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
rb_define_method(cRwWindow, "create", rwwin_create, -1);
|
|
1702
|
+
rb_define_method(cRwWindow, "close", rwwin_close, 0);
|
|
1703
|
+
rb_define_method(cRwWindow, "_hwnd", rwwin_gethandle, 0);
|
|
1704
|
+
rb_define_method(cRwWindow, "alive?", rwwin_alive_p, 0);
|
|
1705
|
+
rb_define_method(cRwWindow, "move", rwwin_move, -1);
|
|
1706
|
+
rb_define_method(cRwWindow, "resize", rwwin_resize, 2);
|
|
1707
|
+
rb_define_method(cRwWindow, "refresh", rwwin_refresh, -1);
|
|
1708
|
+
rb_define_method(cRwWindow, "redraw", rwwin_setredraw, -1);
|
|
1709
|
+
rb_define_method(cRwWindow, "screenpos", rwwin_getscreenpos, 0);
|
|
1710
|
+
rb_define_method(cRwWindow, "clientpos", rwwin_getclientpos, 0);
|
|
1711
|
+
rb_define_method(cRwWindow, "windowsize", rwwin_getwndsize, 0);
|
|
1712
|
+
rb_define_method(cRwWindow, "clientsize", rwwin_getclientsize, 0);
|
|
1713
|
+
rb_define_method(cRwWindow, "setorder", rwwin_setorder, 1);
|
|
1714
|
+
rb_define_method(cRwWindow, "cursorPos", rwwin_getcursorpos, 0);
|
|
1715
|
+
|
|
1716
|
+
/* r/w attributes */
|
|
1717
|
+
rb_define_method(cRwWindow, "caption",rwwin_getcaption, 0);
|
|
1718
|
+
rb_define_method(cRwWindow, "caption=",rwwin_setcaption, 1);
|
|
1719
|
+
rb_define_method(cRwWindow, "visible", rwwin_getvisible, 0);
|
|
1720
|
+
rb_define_method(cRwWindow, "visible=", rwwin_setvisible, 1);
|
|
1721
|
+
rb_define_method(cRwWindow, "idcmd", rwwin_getidcmd, 0);
|
|
1722
|
+
rb_define_method(cRwWindow, "idcmd=", rwwin_setidcmd, 1);
|
|
1723
|
+
rb_define_method(cRwWindow, "parent", rwwin_getparent, 0);
|
|
1724
|
+
rb_define_method(cRwWindow, "parent=", rwwin_setparent, 1);
|
|
1725
|
+
rb_define_method(cRwWindow, "x", rwwin_getx, 0);
|
|
1726
|
+
rb_define_method(cRwWindow, "y", rwwin_gety, 0);
|
|
1727
|
+
rb_define_method(cRwWindow, "w", rwwin_getw, 0);
|
|
1728
|
+
rb_define_method(cRwWindow, "h", rwwin_geth, 0);
|
|
1729
|
+
rb_define_method(cRwWindow, "x=", rwwin_setx, 1);
|
|
1730
|
+
rb_define_method(cRwWindow, "y=", rwwin_sety, 1);
|
|
1731
|
+
rb_define_method(cRwWindow, "w=", rwwin_setw, 1);
|
|
1732
|
+
rb_define_method(cRwWindow, "h=", rwwin_seth, 1);
|
|
1733
|
+
|
|
1734
|
+
/* hook functions */
|
|
1735
|
+
rb_define_method(cRwWindow, "SetWindowSubclass", rwwin_setsubclass, 0);
|
|
1736
|
+
rb_define_method(cRwWindow, "RemoveWindowSubclass", rwwin_removesubclass, 0);
|
|
1737
|
+
|
|
1738
|
+
/* API functions */
|
|
1739
|
+
rb_define_method(cRwWindow, "SetFocus", rwwin_setfocus, 0);
|
|
1740
|
+
rb_define_method(cRwWindow, "SendMessage", rwwin_sendmessage, 3);
|
|
1741
|
+
rb_define_method(cRwWindow, "PostMessage", rwwin_postmessage, 3);
|
|
1742
|
+
rb_define_method(cRwWindow, "GetWindowLong", rwwin_getwndlong, 1);
|
|
1743
|
+
rb_define_method(cRwWindow, "SetWindowLong", rwwin_setwndlong, 2);
|
|
1744
|
+
rb_define_method(cRwWindow, "SetWindowPos", rwwin_setwndpos, 6);
|
|
1745
|
+
rb_define_method(cRwWindow, "GetWindowRect", rwwin_getwindowrect, 0);
|
|
1746
|
+
rb_define_method(cRwWindow, "SetCapture", rwwin_setcapture, 0);
|
|
1747
|
+
rb_define_method(cRwWindow, "ReleaseCapture", rwwin_releasecapture, 0);
|
|
1748
|
+
rb_define_method(cRwWindow, "ShowWindow", rwwin_showwindow, 1);
|
|
1749
|
+
rb_define_method(cRwWindow, "RegisterHotKey", rwwin_registerhotkey, 3);
|
|
1750
|
+
rb_define_method(cRwWindow, "UnregisterHotKey", rwwin_unregisterhotkey, 1);
|
|
1751
|
+
rb_define_method(cRwWindow, "ClientToScreen", rwwin_client2screen, 2);
|
|
1752
|
+
rb_define_method(cRwWindow, "ScreenToClient", rwwin_screen2client, 2);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
/* RwDaialog */
|
|
1756
|
+
VALUE cRwDialog;
|
|
1757
|
+
|
|
1758
|
+
/* TypedData */
|
|
1759
|
+
void rw_dlg_free(void *ptr){
|
|
1760
|
+
RwDialog *rd =ptr;
|
|
1761
|
+
if (rd->rwwin.hwnd) DestroyWindow(rd->rwwin.hwnd);
|
|
1762
|
+
if (rd->rwwin.msgfilter) freeAAtree(rd->rwwin.msgfilter);
|
|
1763
|
+
if (rd->rwwin.handler_ids) freeAAtree(rd->rwwin.handler_ids);
|
|
1764
|
+
free(rd);
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
static size_t
|
|
1768
|
+
rwdlg_memsize(const void *ptr){
|
|
1769
|
+
return ptr ? sizeof(RwDialog) : 0;
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
const rb_data_type_t
|
|
1773
|
+
rwdlg_data_type = { /* parent is rwwin_data_type */
|
|
1774
|
+
"Dialog", {NULL, rw_dlg_free, rwdlg_memsize}, &rwwin_data_type, NULL
|
|
1775
|
+
};
|
|
1776
|
+
|
|
1777
|
+
static VALUE
|
|
1778
|
+
alloc_rw_dialog(VALUE klass){
|
|
1779
|
+
RwDialog *rd;
|
|
1780
|
+
VALUE obj;
|
|
1781
|
+
obj = RwDialog_Data_Make_Struct(klass, rd);
|
|
1782
|
+
rd->rwwin.msgfilter = NULL;
|
|
1783
|
+
rd->rwwin.handler_ids = NULL;
|
|
1784
|
+
return obj;
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
INT_PTR CALLBACK
|
|
1788
|
+
RwDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
|
|
1789
|
+
VALUE wobj;
|
|
1790
|
+
if(uMsg==WM_INITDIALOG){
|
|
1791
|
+
RwDialog *rd;
|
|
1792
|
+
VALUE dobj = lParam;
|
|
1793
|
+
RwDialog_Data_Get_Struct(dobj, rd);
|
|
1794
|
+
rd->rwwin.hwnd = hWnd;
|
|
1795
|
+
Register_win(hWnd, dobj);
|
|
1796
|
+
}
|
|
1797
|
+
if(wobj = Get_win(hWnd)){
|
|
1798
|
+
RwWindow *rw = DATA_PTR(wobj);
|
|
1799
|
+
if(uMsg == WM_PAINT){
|
|
1800
|
+
if (rw->msgfilter) {
|
|
1801
|
+
AAnode *nd = aaSearch(rw->msgfilter, WM_PAINT);
|
|
1802
|
+
if (nd) {
|
|
1803
|
+
PAINTSTRUCT ps;
|
|
1804
|
+
RwBaseHandler *basehandler = nd->val;
|
|
1805
|
+
HDC hdc = BeginPaint(rw->hwnd, &ps);
|
|
1806
|
+
dispatch_wm_paint_handler(wobj, basehandler, hdc);
|
|
1807
|
+
EndPaint(rw->hwnd, &ps);
|
|
1808
|
+
return 0;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
} else {
|
|
1812
|
+
LRESULT ret;
|
|
1813
|
+
if (uMsg==WM_ACTIVATE) activewin = LOWORD(wParam) ? rw : NULL;
|
|
1814
|
+
ret=do_wm_default(wobj, &uMsg, &wParam, &lParam);
|
|
1815
|
+
if (ret){
|
|
1816
|
+
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, ret);
|
|
1817
|
+
return TRUE; /* skip default dlgdproc */
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
switch(uMsg){
|
|
1822
|
+
case WM_CLOSE:
|
|
1823
|
+
if(((RwDialog*)rw)->modal) {
|
|
1824
|
+
EndDialog(hWnd, Qfalse);
|
|
1825
|
+
if(aaCount(winlist)==0) rwwin_finalize();
|
|
1826
|
+
} else {
|
|
1827
|
+
DestroyWindow(hWnd);
|
|
1828
|
+
}
|
|
1829
|
+
return TRUE;
|
|
1830
|
+
case WM_DESTROY:
|
|
1831
|
+
rw->hwnd = NULL;
|
|
1832
|
+
Unregister_win(hWnd);
|
|
1833
|
+
if(aaCount(winlist)==0){
|
|
1834
|
+
rwwin_finalize();
|
|
1835
|
+
PostQuitMessage(wParam);
|
|
1836
|
+
return 0;
|
|
1837
|
+
}
|
|
1838
|
+
return TRUE;
|
|
1839
|
+
default:
|
|
1840
|
+
break;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
return 0;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
static VALUE
|
|
1847
|
+
rwdialog_create(int argc, VALUE *argv, VALUE self){
|
|
1848
|
+
DLGTEMPLATE *template;
|
|
1849
|
+
VALUE v_parent, v_modal, v_param;
|
|
1850
|
+
INT_PTR ret;
|
|
1851
|
+
HWND hparent = NULL;
|
|
1852
|
+
BOOL template_given = FALSE;
|
|
1853
|
+
RwDialog *rd = DATA_PTR(self);
|
|
1854
|
+
|
|
1855
|
+
if(rb_typeddata_is_kind_of(argv[2], &cstruct_data_type)) {
|
|
1856
|
+
VALUE v_template;
|
|
1857
|
+
CStructData *cs;
|
|
1858
|
+
rb_scan_args(argc, argv, "31", &v_parent, &v_modal, &v_template, &v_param);
|
|
1859
|
+
CStruct_Data_Get_Struct(v_template, cs);
|
|
1860
|
+
template_given = TRUE;
|
|
1861
|
+
template = (DLGTEMPLATE*)(cs->dtstr + cs->dtoffset);
|
|
1862
|
+
} else { /* create default template */
|
|
1863
|
+
VALUE v_style, v_exstyle;
|
|
1864
|
+
rb_scan_args(argc, argv, "23", &v_parent, &v_modal, &v_style, &v_exstyle, &v_param);
|
|
1865
|
+
RW_CALLOC(template, sizeof(DLGTEMPLATE) + 4);
|
|
1866
|
+
template->style = NIL_P(v_style) ?
|
|
1867
|
+
(WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION | DS_MODALFRAME) : NUM2UINT(v_style);
|
|
1868
|
+
template->dwExtendedStyle = NIL_P(v_exstyle) ? 0 : NUM2UINT(v_exstyle);
|
|
1869
|
+
rd->param = v_param;
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
rd->modal = (!NIL_P(v_modal) && v_modal) ? TRUE : FALSE;
|
|
1873
|
+
if(!NIL_P(v_parent)){
|
|
1874
|
+
RwWindow *rw;
|
|
1875
|
+
RwWindow_Data_Get_Struct(v_parent, rw);
|
|
1876
|
+
hparent = rw->hwnd;
|
|
1877
|
+
}
|
|
1878
|
+
if(rd->modal){
|
|
1879
|
+
ret = DialogBoxIndirectParam(hInstance, template, hparent, RwDlgProc, self);
|
|
1880
|
+
if (ret==-1) rb_raise(rb_eRuntimeError,"create modal dialog failed");
|
|
1881
|
+
} else {
|
|
1882
|
+
HWND hwnd;
|
|
1883
|
+
hwnd = CreateDialogIndirectParam(hInstance, template, hparent, RwDlgProc, self);
|
|
1884
|
+
if (!hwnd) rb_raise(rb_eRuntimeError,"create modeless dialog failed");
|
|
1885
|
+
ShowWindow(hwnd, TRUE);
|
|
1886
|
+
ret = Qnil;
|
|
1887
|
+
}
|
|
1888
|
+
if(!template_given) {
|
|
1889
|
+
free(template);
|
|
1890
|
+
}
|
|
1891
|
+
return (VALUE)ret;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
static VALUE
|
|
1895
|
+
rwdialog_close(int argc, VALUE *argv, VALUE self){
|
|
1896
|
+
VALUE v_ret;
|
|
1897
|
+
RwWindow *rw;
|
|
1898
|
+
RwDialog *rd = DATA_PTR(self);
|
|
1899
|
+
rw = (RwWindow*)rd;
|
|
1900
|
+
RwCheckWindow(rw);
|
|
1901
|
+
rb_scan_args(argc, argv, "01", &v_ret);
|
|
1902
|
+
if (rd->modal){ //fprintf(stderr, "@%d: v_ret=%lld\n", __LINE__, v_ret);
|
|
1903
|
+
// return rw_call_without_gvl_2(rw->nthread_id, (FARPROC)EndDialog, (ULONG_PTR)rw->hwnd,
|
|
1904
|
+
// (ULONG_PTR)v_ret);
|
|
1905
|
+
return EndDialog(rw->hwnd, (INT_PTR)v_ret);
|
|
1906
|
+
} else {
|
|
1907
|
+
DestroyWindow(((RwWindow*)rd)->hwnd);
|
|
1908
|
+
return 0;
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
static VALUE
|
|
1913
|
+
rwdialog_getparam(VALUE self){
|
|
1914
|
+
RwDialog *rd = DATA_PTR(self);
|
|
1915
|
+
RwCheckWindow((RwWindow*)rd);
|
|
1916
|
+
return rd->param;
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
static void
|
|
1920
|
+
rw_init_RwDialog(){
|
|
1921
|
+
cRwDialog = rb_define_class_under(mRwin, "Dialog", cRwWindow);
|
|
1922
|
+
rb_define_alloc_func(cRwDialog, alloc_rw_dialog);
|
|
1923
|
+
rb_define_method(cRwDialog, "create", rwdialog_create, -1);
|
|
1924
|
+
rb_define_method(cRwDialog, "close", rwdialog_close, -1);
|
|
1925
|
+
rb_define_method(cRwDialog, "param", rwdialog_getparam, 0);
|
|
1926
|
+
|
|
1927
|
+
rb_undef_method(cRwDialog, "SetWindowSubclass");
|
|
1928
|
+
rb_undef_method(cRwDialog, "RemoveWindowSubclass");
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
/* Initializing */
|
|
1932
|
+
void
|
|
1933
|
+
Init_rw_windows(){
|
|
1934
|
+
rw_init_RwWindow();
|
|
1935
|
+
rw_init_RwDialog();
|
|
1936
|
+
}
|