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


HSPTV!掲示板


未解決 解決 停止 削除要請

2018
0707
透視ウィンドウ、または恐怖のデスクトップ2未解決


リンク

2018/7/7(Sat) 00:09:02|NO.84728

ウィンドウドラッグ中も処理が継続されるコードと画面キャプチャのコード
を切り貼りしてこのようなものを作ってみました。
ウインドウドラッグするとデスクトップ上に見えないはずの文字が!
スペース連打すると文字が増えます。
画像データを用意して服が透ける!などのしょうもない利用法を考えていますが、
Win32APIに関しては何も解っていないので、現時点での動作確認も兼ねて
プログラム的にマズい処理をしていないかなどご意見等あればお願いしたいです。

#uselib "user32.dll" #func global SetTimer "SetTimer" int,int,int,int #func global KillTimer "KillTimer" int,int #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #cfunc CreateDC "CreateDCA" sptr,sptr,sptr,int #func DeleteDC "DeleteDC" int randomize screen 0,400,400,0,ginfo(20)+16,0 buffer 1,ginfo(20),ginfo(21),0 hdcScreen = CreateDC("DISPLAY",0,0,0) BitBlt hdc,0,0,ginfo(20),ginfo(21),hdcScreen,0,0,0x00CC0020|0x40000000 DeleteDC hdcScreen gsel 0 width ,,64,64 gsel 1 color 255,0,0 font msmincho,60 gosub *tasukete gsel 0 mcr_hwnd@=hwnd #define customwait(%1) %tcw \ SetTimer mcr_hwnd@,9983 , %1 , 0 :\ oncmd gosub *m%i,0x0113 :\ return 0 : \ *m%o : \ KillTimer mcr_hwnd@,9983 gosub *main stop *main repeat redraw 0:color:boxf gcopy 1,ginfo(4)+4,ginfo(5)+30,ginfo(12),ginfo(13) gosub *keys redraw 1 customwait 1 loop *keys stick ky,0 if ky&&16:gosub *tasukete return *tasukete gsel 1 repeat 10 pos rnd(ginfo(20)),rnd(ginfo(21)) mes "タスケテ…" loop gsel 0 return



この記事に返信する


K-s

リンク

2018/7/8(Sun) 04:48:45|NO.84734

ウィンドウタイマーは一定時間毎の処理で、基本最初に一回だけ設定すればOKです。
waitのようにループ中に毎回設定するのはあまり良くないかと思われます。
HSP的にもrepeat内からreturnで脱出するのも危険…

#uselib "user32.dll" #func global SetTimer "SetTimer" int,int,int,int #func global KillTimer "KillTimer" int,int #func ScreenToClient "ScreenToClient" int,var #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #cfunc CreateDC "CreateDCA" sptr,sptr,sptr,int #func DeleteDC "DeleteDC" int randomize screen 0,400,400,2 wait 50 buffer 1,ginfo(20),ginfo(21),0 hdcScreen = CreateDC("DISPLAY",0,0,0) BitBlt hdc,0,0,ginfo(20),ginfo(21),hdcScreen,0,0,0x00CC0020|0x40000000 DeleteDC hdcScreen color 255,0,0 font msmincho,60 gosub *tasukete gsel 0,1 gosub *draw mcr_hwnd=hwnd SetTimer mcr_hwnd, 9983, 1, 0 oncmd gosub *draw,0x0113 onexit *bye stop *bye KillTimer mcr_hwnd, 9983 end *draw gosub *keys redraw 0 client=0,0 ScreenToClient hwnd,client gcopy 1,-client.0,-client.1,ginfo(12),ginfo(13) redraw 1 return *keys stick ky,0 if ky&&16:gosub *tasukete return *tasukete gsel 1 repeat 10 pos rnd(ginfo(20)),rnd(ginfo(21)) mes "タスケテ…" loop gsel 0 return

今回の例だとタイマーを使わずウィンドウの移動メッセージでも処理できます。
キー入力はWM_KEYDOWNで処理したかったのですがドラッグ中は飛んでこないみたい…

#uselib "user32.dll" #func ScreenToClient "ScreenToClient" int,var #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #cfunc CreateDC "CreateDCA" sptr,sptr,sptr,int #func DeleteDC "DeleteDC" int randomize screen 0,400,400,2 wait 50 buffer 1,ginfo(20),ginfo(21),0 hdcScreen = CreateDC("DISPLAY",0,0,0) BitBlt hdc,0,0,ginfo(20),ginfo(21),hdcScreen,0,0,0x00CC0020|0x40000000 DeleteDC hdcScreen color 255,0,0 font msmincho,60 gosub *tasukete gsel 0,1 gosub *draw oncmd gosub *draw,0x0003 ; WM_MOVE onkey gosub *keys_on stop *draw gosub *keys redraw 0 client=0,0 ScreenToClient hwnd,client gcopy 1,-client.0,-client.1,ginfo(12),ginfo(13) redraw 1 return *keys stick ky,0 if ky&&16:gosub *tasukete return *keys_on if lparam>>30 : return if wparam==32 { gosub *tasukete gosub *draw } return *tasukete gsel 1 repeat 10 pos rnd(ginfo(20)),rnd(ginfo(21)) mes "タスケテ…" loop gsel 0 return

ついでにデスクトップの更新にも追従させたくなって、
キャプチャ使わずレイヤードウィンドウでもやってみました。毎回キャプチャは重そうなので。
透過色の都合上背景によってはフォントのジャギが目立つ…

#uselib "user32.dll" #func ScreenToClient "ScreenToClient" int,var #cfunc GetWindowLong "GetWindowLongA" int, int #func SetWindowLong "SetWindowLongA" int, int, int #func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int, int, int, int buffer 1,ginfo(20),ginfo(21),0 color ; 透過色 boxf color 255,0,0 font msmincho,60 gosub *tasukete randomize screen 0,400,400 : gsel 0, 2 SetWindowLong hwnd, -20, GetWindowLong(hwnd, -20) | 0x00080000 ; GWL_EXSTYLE, WS_EX_LAYERED SetLayeredWindowAttributes hwnd, 0x000000, 0, 1 ; 透過色 oncmd gosub *draw,0x0003 ; WM_MOVE onkey gosub *keys_on gosub *draw stop *draw gosub *keys redraw 0 client=0,0 ScreenToClient hwnd,client gcopy 1,-client.0,-client.1,ginfo(12),ginfo(13) redraw 1 return *keys stick ky,0 if ky&&16:gosub *tasukete return *keys_on if lparam>>30 : return if wparam==32 { gosub *tasukete gosub *draw } return *tasukete gsel 1 repeat 10 pos rnd(ginfo(20)),rnd(ginfo(21)) mes "タスケテ…" loop gsel 0 return



リンク

2018/7/8(Sun) 18:53:27|NO.84737

御二方ご教示ありがとうございました。
その後最終的に作りたいものに改良して修正も組み込んでみました。
実行には、適当な画像ファイル2枚(動サイズの差分的なのが判りやすい)必要です。
レイヤードウィンドウ版の軽快な動作とデスクトップ追従は理想なのですが
自分の科学力ではこのへんが限界です。新たな指摘点、改良版などあれば是非。

#uselib "user32.dll" #func ScreenToClient "ScreenToClient" int,var #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #cfunc CreateDC "CreateDCA" sptr,sptr,sptr,int #func DeleteDC "DeleteDC" int RoupeX=200,300,400,500,600,700 RoupeY=50,100,200,300,400,500,600,700 XN=0:YN=2 screen 0,700,700,0 title"ルーペ" gsel 0,-1 buffer 1,ginfo(20),ginfo(21),0 //デスクトップ保存バッファ gosub *re_load gsel 0,2 width 200,200,6,6 gosub *draw oncmd gosub *draw,0x0003 onkey gosub *keys stop //////////////////////////////////////////////////////// *draw gsel 0 redraw 0 client=0,0 ScreenToClient hwnd,client gcopy 1,-client.0,-client.1,ginfo(12),ginfo(13) redraw 1 return *keys if iparam==90{XN++:XN\=6:gsel 0 //ルーペ横幅変更 width RoupeX.XN,RoupeY.YN} if iparam==88{YN++:YN\=8:gsel 0 //ルーペ縦幅変更 width RoupeX.XN,RoupeY.YN} if iparam==32:gosub *re_shot //再スクショ if iparam==13:gosub *re_load //画像再選択 gosub *draw return *re_load //画像読み込み if initial==0{ //初期設定 screen 2,ginfo(20),ginfo(21),0,0,0 width 256,256,0,0:boxf color 255,255,255:mes"Suke-Ru v1.0\n1枚目に通常画像\n2枚目に透過画像を選んでね\n\n使用キー\nZ:ルーペ横幅変更" mes"X:ルーペ縦幅変更\nENTER:画像変更\nSPACE:スクショ更新\n\nクリック:ルーペ動かす" pos 0,0 buffer 3,ginfo(20),ginfo(21) //通常画像バッファ buffer 4,ginfo(20),ginfo(21) //透視画像バッファ initial=1} dialog "png|jpg|bmp",16,"通常画像" filename1=refstr gsel 3:picload filename1 picX=ginfo(26):picY=ginfo(27) Aspe=(1.0*ginfo(21))/(1.0*ginfo(20)) Bai=1.0 if (Aspe*picX>picY)&&(picX>ginfo(20)):Bai=1.0*ginfo(20)/picX if (Aspe*picX<=picY)&&(picY>(ginfo(21)-80)):Bai=1.0*(ginfo(21)-80)/picY dialog "png|jpg|bmp",16,"透過画像" filename2=refstr gsel 4:picload filename2 gosub *re_shot return *re_shot //バッファ更新 gsel 0,-1 gsel 2:width Bai*picX,Bai*picY gzoom Bai*picX,Bai*picY,4,0,0,picX,picY,1 //透過画像表示して gsel 1 //スクショとる hdcScreen = CreateDC("DISPLAY",0,0,0) BitBlt hdc,0,0,ginfo(20),ginfo(21),hdcScreen,0,0,0x00CC0020|0x40000000 DeleteDC hdcScreen //通常画像を上書きする gsel 2:gzoom Bai*picX,Bai*picY,3,0,0,picX,picY,1 gsel 0,2 return



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