HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
1217
名無しサブクラス化4解決


名無し

リンク

2016/12/17(Sat) 17:36:00|NO.77604

コントロールのサブクラス化はどのようにして行うのでしょうか。



この記事に返信する


tds12

リンク

2016/12/17(Sat) 19:32:50|NO.77615

コールバック関数を用意する必要があります。
その方法にはいくつかあります。
1.C++などで必要な関数を持ったDLLを作りそのポインタを使う
2.専用にマシン語を用意してスクリプトに埋め込む
3.コールバック用のプラグインを使ってサブルーチンを呼ばせる
4.コールバック用のモジュールを使ってサブルーチンを呼ばせる

1は、一番闇の少ない方法ですが、DLLを作るまでが比較的難しい方法です。
2は、ほかの人のモジュールは使いたくなくてDLLも同梱したくない人向けで、
一番難しい方法です。
3は、HSP3でよく使われる方法です。サブクラス化して処理内容はHSPで書けます。
情報も一番多く、闇も隠されています。
4は、HSPで書きたいけどDLLは同梱したくない人向けです。
情報は少なく、闇の気配がしないでもないです。
1と2は動作が軽いかわりに、書くのが面倒です。
3と4は書くのが楽なかわりに、動作の負荷が高い方法です。

1については、C++等用の一般的な解説を見てください。
2については↓
http://chokuto.ifdef.jp/urawaza/mcn/index.html
3については↓
http://hsp.tv/make/tool1.html
4については↓
http://hsp.tv/play/pforum.php?mode=pastwch&num=62130

#funcの関数ポインタはvarptrで取得できます。

いずれかでポインタを取得したら、
GetWindowLongとSetWindowLongを
GWL_WNDPROCについて呼んで、
サブクラス化し、
コールバック関数内でCallWindowProcで
サブクラスのほうを呼びます。



名無し

リンク

2016/12/18(Sun) 10:08:00|NO.77629


#include "hscallbk.as" #uselib "user32.dll" #cfunc CallWindowProc "CallWindowProcA" sptr,sptr,sptr,sptr,sptr #cfunc GetWindowLong "GetWindowLongA" sptr,sptr #func SetWindowLong "SetWindowLongA" sptr,sptr,sptr #define GWL_WNDPROC 0xFFFFFFFC #define WM_RBUTTONDOWN 0x00000204 #uselib "" #func _NewButtonProc "" int, int, int, int setcallbk NewButtonProc, _NewButtonProc, *OnNewButtonProc screen 0, 640, 480 button gosub "button", *click hButton = objinfo_hwnd(stat) pfnDefButtonProc = GetWindowLong(hButton, GWL_WNDPROC) SetWindowLong hButton, GWL_WNDPROC, varptr(NewButtonProc) stop *OnNewButtonProc _hwnd = callbkarg(0) uMsg = callbkarg(1) _wparam = callbkarg(2) _lparam = callbkarg(3) if uMsg == WM_RBUTTONDOWN { gosub *rclick return 0 } return CallWindowProc(pfnDefButtonProc, _hwnd, uMsg, _wparam, _lparam) *click dialog "click" return *rclick dialog "rclick" return
参考:http://eternalwindows.jp/control/controlbase/controlbase05.html
一応できたのですが、いくつか質問があります。
まず、GetWindowLongPtrを呼び出すと失敗します。msdnでは32,64ビットどちらも使えるような
記述があるのですが、こちら
http://hwada.hatenablog.com/entry/20071016/1192519595
では、32ビットではGetWindowLongのエイリアスとなると書いてあるので、結局VC++のヘッダで
マクロ定義されているだけだということでしょうか。
あと、ここではWM_RBUTTONDOWNでreturn 0を行っていますが、デフォルトの挙動を行わせるために、
そのままCallWindowProcを呼び出した方がいいのでしょうか。
よろしくお願いします。



tds12

リンク

2016/12/18(Sun) 10:35:44|NO.77630

>結局VC++のヘッダで
はい、ただの#defineでありGetWindowLongです。

>デフォルトの挙動を行わせるために
デフォルトのほうに伝えたくなければ呼びませんが、
WM_RBUTTONDOWNについては処理されていないようなので
どちらでも問題なさそうです。



名無し

リンク

2016/12/18(Sun) 14:55:06|NO.77637

ありがとうございました。



ONION software Copyright 1997-2021(c) All rights reserved.