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


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0317
とあるプログラマコールバック先(ラベル)でのモジュール型変数のモジュール変数取得について1未解決


とあるプログラマ

リンク

2020/3/17(Tue) 14:09:00|NO.89735

参考 (http://hsp.tv/play/pforum.php?mode=pastwch&num=85479)
のNO.85494より「2. モジュール空間内でラベルをコールバックさせる。」

こちらの内容を元にラベルのジャンプ先で一時的にモジュール型変数のモジュール変数(紛らわしさ回避のため以下、メンバ変数)を取得できることを知ったのですが、
どうやらgosubでのジャンプ先では取得可能なもののコールバックによるジャンプの場合取得ができないようです。



#include "user32.as" #include "modclbk3.hsp" #define global NULLPTR 0x00000000 #define global NULL 0x00000000 #define global WS_OVERLAPPEDWINDOW 0x00CF0000 #define global SW_SHOWNORMAL 0x00000001 #define global GWL_WNDPROC 0xFFFFFFFC #define global WM_CLOSE 0x00000010 #define global WM_LBUTTONDOWN 0x00000201 #module test_module a #modinit a = 100 newclbk3 hWindowProc, 4, *clbkWindowProc if (hWindowProc == nullptr) : dialog "create callback failed" : end winobj "hspwnd0", "test window", NULL, WS_OVERLAPPEDWINDOW, 640, 480, NULL, NULL if (stat == -1) : dialog "create window failed" : end hTestWindow = objinfo_hwnd(stat) SetWindowLong hTestWindow, GWL_WNDPROC, hWindowProc //プロシージャ変更 if (stat == 0) : dialog "change WndProc failed" : end ShowWindow hTestWindow, SW_SHOWNORMAL gosub *testlabel return 1 #modcfunc getA //aのgetter関数 return a *testlabel logmes "a is " + a + "" //これは成功する return *clbkWindowProc clbkargprotect msg if (msg.1 == WM_CLOSE) : PostMessage hwnd, WM_CLOSE, msg.2, msg.3 // if (msg.1 == WM_LBUTTONDOWN) : logmes "a is " + getA(thismod) + "" // こっちも無理 (非コメントアウトで確認) if (msg.1 == WM_LBUTTONDOWN) : logmes "a is " + a@test_module + "" // これはエラー30「無効な名前が〜」が発生 return DefWindowProc(msg.0, msg.1, msg.2, msg.3) // クラス「hspwnd0」側のプロシージャを呼ぶとエラーダイアログが表示されなくなる #global newmod hoge, test_module

この例ですと*testlabel内(gosub)だとメンバ変数 aの内容を取得できますが*clbkWindowProc(コールバック)だと取得不可です。thismodによるgetter関数での取得も無理でした。
(恐らくmodclbk3がgosubによるジャンプをしていないためにgosubのジャンプと処理が違ってアクセスができない?)


コールバック先からモジュール型変数のメンバ変数を取得することはできないのでしょうか。



この記事に返信する


とあるプログラマ

リンク

2020/3/17(Tue) 17:25:51|NO.89737

かなり強引な方法ですがGWL_USERDATAにモジュール変数(メンバ変数)の内容を格納した変数へのポインタを渡す方法を試してみました。

一応これで望んだとおりの動作をするようにはなりましたが、もしこれよりスマートな方法をご存じな方がいれば是非ご教授お願い致します。


#include "user32.as" #include "modclbk3.hsp" #define global NULLPTR 0x00000000 #define global NULL 0x00000000 #define global WS_OVERLAPPEDWINDOW 0x00CF0000 #define global SW_SHOWNORMAL 0x00000001 #define global GWL_WNDPROC 0xFFFFFFFC #define global WM_CLOSE 0x00000010 #define global WM_LBUTTONDOWN 0x00000201 #define global WM_RBUTTONDOWN 0x00000204 #define global GWL_USERDATA 0xFFFFFFEB #module test_module TESTINFO, \ a, b, c #modinit str title_ a = rnd(1000) b = rnd(1000) c = rnd(1000) // TESTINFOに各モジュール変数(メンバ変数)のポインタを格納する TESTINFO.0 = varptr(a) TESTINFO.1 = varptr(b) TESTINFO.2 = varptr(c) newclbk3 hWindowProc, 4, *clbkWindowProc if (hWindowProc == nullptr) : dialog "create callback failed" : end winobj "hspwnd0", title_, NULL, WS_OVERLAPPEDWINDOW, 640, 480, NULL, NULL //ウィンドウ作成 if (stat == -1) : dialog "create window failed" : end hTestWindow = objinfo_hwnd(stat) SetWindowLong hTestWindow, GWL_WNDPROC, hWindowProc //プロシージャ変更 if (stat == 0) : dialog "change WndProc failed" : end SetWindowlong hTestWindow, GWL_USERDATA, varptr(TESTINFO) // GWL_USERDATA領域にTESTINFOのポインタを格納 ShowWindow hTestWindow, SW_SHOWNORMAL return 1 *clbkWindowProc clbkargprotect msg if (msg.1 == WM_CLOSE) : PostMessage hwnd, WM_CLOSE, msg.2, msg.3 // 閉じるときはアプリケーション全体を終了する if (msg.1 == WM_LBUTTONDOWN || msg.1 == WM_RBUTTONDOWN) { lpTESTINFO = GetWindowLong(msg.0, GWL_USERDATA) // TESTINFOのポインタを取得 if (lpTESTINFO) { dupptr dupTESTINFO, lpTESTINFO, 4 * 3, 4 // dupptrでTESTINFOのクローンを作成 dupptr dupa, dupTESTINFO.0, 4, 4 // a のクローンを作成 dupptr dupb, dupTESTINFO.1, 4, 4 // b のクローンを作成 dupptr dupc, dupTESTINFO.2, 4, 4 // c のクローンを作成 if (msg.1 == WM_LBUTTONDOWN) { // 左クリックしたときは内容を表示する dialog "a = " + dupa + "\nb = " + dupb + "\nc = " + dupc + "" }else { // 右クリックしたときは値をランダムに変える dupa = rnd(1000) dupb = rnd(1000) dupc = rnd(1000) } } } return DefWindowProc(msg.0, msg.1, msg.2, msg.3) #global randomize newmod hoge, test_module, "test window 1" newmod hoge2, test_module, "test window 2" gsel 0, 1 pos 0, 0 mes "test windowの内部を" mes "左クリックするとモジュール変数(メンバ変素)を表示します" mes "右クリックするとモジュール変数(メンバ変素)をランダムに変更します"



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