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


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
0313
ろがーウィンドウの透明化・半透明化について3解決


ろがー

リンク

2013/3/13(Wed) 02:00:56|NO.52914

SetLayeredWindowAttributes関数を使いウィンドウからmesdoxの文字以外の部分の透明化を行ったのですが、
この際メッセージボックスのテキストをコピーしようとすると
透明化されてない文字のドットの上にピンポイントでカーソルを持って行かなければ
カーソルが文字選択モードにならずまた右クリックメニューも開けないため、
テキストのコピーが非常にしづらいです。
SetLayeredWindowAttributes関数の透過を透過色ではなくアルファブレンドによる透過にすると
その問題は起きないのですが、今度は文字まで薄くなってしまい見にくくなります

・ウィンドウの特定の色のみ半透明化する
・カーソルを強制的に選択モードなどにするなどしてコピーや右クリックメニューを開けるようにする
というような感じで回避する方法などはありますか?

またmesboxの非編集モードでテキストの色を変える方法などはあるでしょうか?



この記事に返信する


暇人

リンク

2013/3/24(Sun) 18:31:05|NO.53211

>・ウィンドウの特定の色のみ半透明化する
UpdateLayeredWindow使ってビットマップオブジェクトでドット毎の
半透明の濃度を変えるのは出来るけど
目的の事が出来るかは分からない

>またmesboxの非編集モードでテキストの色を変える方法などはあるでしょうか?
ある
編集できるのと出来ないので飛んでくるメッセージナンバーが違うだけ


>カーソルを強制的に選択モードなどにするなどしてコピーや右クリックメニューを開けるようにする
かなり強引って言うか
Vista以降じゃ使えないかもしれない方法で目的は達成できた

マウスを受け付けないレイヤードウィンドウ作りそれを背景に
透明度1のmesboxを配置したメインウィンドウを作り
透明度を一時的に255にして背景にコピーして直ぐに1に戻すって方法


↓のモジュールを使う
http://hsp.tv/play/pforum.php?mode=pastwch&num=46392



#include "mod_d3d9vsync.hsp" #uselib "user32.dll" #cfunc GetWindowLong "GetWindowLongA" int , int #func SetWindowLong "SetWindowLongA" int , int , int #func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int , int , int , int #func SendMessageA "SendMessageA" int , int , int , int #func PostMessageA "PostMessageA" int , int , int , int #func SetWindowPos "SetWindowPos" int, int, int, int, int, int, int #cfunc GetDC "GetDC" int #uselib "gdi32.dll" #cfunc CreateDC "CreateDCA" sptr,sptr,sptr,int #func DeleteDC "DeleteDC" int #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #func global GetStockObject "GetStockObject" int #func global SetTextColor "SetTextColor" sptr,sptr #func global SetBkColor "SetBkColor" sptr,sptr #func global SetBkMode "SetBkMode" sptr,sptr #func global DeleteObject "DeleteObject" sptr #func global CreateSolidBrush "CreateSolidBrush" sptr #define WM_LBUTTONDOWN 0x0201 #define WM_MOVING 0x0216 #define SWP_NOSIZE 0x0001 #define SWP_NOZORDER 0x0004 #define SWP_NOACTIVATE 0x0010 #define NULL 0 #define SRCCOPY 0x00CC0020 #define CAPTUREBLT 0x40000000 #const SWP_NOMOVE 0x02 #const SWP_NOREDRAW 0x08 #const SWP_FRAMECHANGED 0x020 #const SWP_SHOWWINDOW 0x040 #const SWP_HIDEWINDOW 0x080 #const SWP_NOCOPYBITS 0x0100 #const SWP_NOOWNERZORDER 0x0200 #const SWP_DRAWFRAME SWP_FRAMECHANGED #const SWP_NOREPOSITION SWP_NOOWNERZORDER #define WS_EX_TRANSPARENT $20 #define WS_EX_TOOLWINDOW $80 ; 色指定用のRGBマクロ (0x00BBGGRR形式へ変換) #define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16) #define WHITE_BRUSH 0 #define LTGRAY_BRUSH 1 #define GRAY_BRUSH 2 #define DKGRAY_BRUSH 3 #define BLACK_BRUSH 4 #define NULL_BRUSH 5 #define HOLLOW_BRUSH 5 //メインウィンドウ(見えないくらいの半透明) wsx=400 wsy=300 mainid=0 bgscr mainid, wsx, wsy, 0, 300, 300 hwnds(mainid)=hwnd hdcs(mainid)=hdc objmode 0 pos 10, 10 : button goto "終了する", *exit sdim txt,1024 txt={"メインウィンドウにmesboxを置き 見えない半透明にして 背景用ウィンドウを白透明で 一瞬不透明にしたメインウィンドウからコピー"} mbsx=300 mbsy=200 mbx=50 mby=70 pos mbx,mby mesbox txt,mbsx,mbsy,1 mid=stat hMesbox(mid) = objinfo(stat, 2) obj_hdc(mid)=GetDC(hMesbox(mid)) GetStockObject LTGRAY_BRUSH hEDITbrush = stat GetStockObject LTGRAY_BRUSH hSTATICbrush = stat //LTGRAY #define COLORKEY $C0C0C0 #define brushCOLORKEY RGB(((COLORKEY>>16)&$ff),((COLORKEY>>8)&$ff),(COLORKEY&$ff)) //背景ウィンドウ(カラキー白を透明) bkgdid=1 bgscr bkgdid, wsx, wsy,2 , 300, 300 color 192,192,192:boxf objmode 0 hwnds(bkgdid) = hwnd hdcs(bkgdid)=hdc pos 10, 10 : button goto "終了する", *exit color 50,50,200 :boxf 0,0, wsx,45 color 255,100,255:pos 80, 20 : mes "レイヤードウィンドウを使ったテスト" color 250,250,250:boxf mbx,mby, mbsx+mbx,mby+mbsy wait 1 #define GWL_EXSTYLE -20 #define GWL_STYLE -16 // STYLE(hwnd,追加STYLE,削除STYLE) #define ctype STYLE(%1,%2,%3=0) %1,GWL_STYLE,((GetWindowLong(%1,GWL_STYLE) | (%2)) | (%3)) ^ (%3) #define ctype EXSTYLE(%1,%2,%3=0) %1,GWL_EXSTYLE,((GetWindowLong(%1,GWL_EXSTYLE) | (%2)) | (%3)) ^ (%3) //スタイルの追加 #define WS_EX_LAYERED 0x00080000 SetWindowLong EXSTYLE(hwnds(mainid),WS_EX_LAYERED) SetWindowLong EXSTYLE(hwnds(bkgdid),WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW) #define LWA_COLORKEY 1 #define LWA_ALPHA 2 SetLayeredWindowAttributes hwnds(mainid), 0,255, LWA_ALPHA SetLayeredWindowAttributes hwnds(bkgdid), COLORKEY, 0, LWA_COLORKEY SetWindowPos hwnds(mainid),0 ,0,0 ,0,0 ,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW SetWindowPos hwnds(bkgdid),0 ,0,0 ,0,0 ,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW wait 10 gsel mainid,1 d3d9vsync_init if stat < 0 { if -5 ! stat {dialog "GetRasterStatusを使用できない環境です":end} } #define WM_CTLCOLORSTATIC $0138 #define WM_CTLCOLOREDIT $133 objenable mid,0 oncmd gosub *CTLCOLOREDIT, WM_CTLCOLOREDIT oncmd gosub *CTLCOLORSTATIC, WM_CTLCOLORSTATIC objenable mid,1 //色反映 oncmd gosub *LBUTTONDOWN , WM_LBUTTONDOWN oncmd gosub *MOVING, WM_MOVING onexit *exit repeat gsel (mainid) repeat _Sleep@mod_d3d9vsync 1 GetRasterStatus v,r //VBlankとラスター位置取得 if v{break} //VBlank中 loop repeat GetRasterStatus v,r //VBlankとラスター位置取得 //ラスターが実行ウィンドウより下なら抜ける if r>(0.95*ginfo_wy2) or (ginfo_wy2 >= ginfo_dispy){break} //0.95はウィンドウの下部が画面の下のほうだとウィンドウの上のほうが点滅しやすくなるから調整 if (ginfo_wy2-r)>250 {_Sleep@mod_d3d9vsync 1} //目的の位置まで250以上有ったら1msスリープ loop SetLayeredWindowAttributes hwnds(mainid), 0, 255, LWA_ALPHA //ALPHAモードで不透明設定 //mesboxを見えるようにして背景にコピー BitBlt hdcs(bkgdid), mbx+2,mby+2, mbsx,mbsy, obj_hdc(mid), 0, 0, SRCCOPY | CAPTUREBLT //XPの場合CAPTUREBLTは必須 Vista以降なら無くて良い SetLayeredWindowAttributes hwnds(mainid), 0, 1, LWA_ALPHA //ALPHAモードで判定が残る透明に設定 gsel bkgdid redraw 1 redraw 0 gsel (mainid) if ginfo_act=mainid{ objsel -1 obj_bak(mainid)=stat } await 10 if ginfo_act<0{ noact++ }else{ if noact{ getkey clk,1 if clk=0{ noact=0 gsel bkgdid,1 gsel mainid,1 if obj_bak(mainid)>=0 {objsel obj_bak(mainid)} } } } loop stop *CTLCOLOREDIT if hMesbox(mid) = lparam { SetBkMode wparam,2 SetTextColor wparam, RGB($C0, $ff, $C0) SetBkColor wparam, brushCOLORKEY return hEDITbrush } return *CTLCOLORSTATIC if hMesbox(mid) = lparam { SetBkMode wparam,1 SetTextColor wparam, RGB($00, $ff, $88) return hSTATICbrush } return *MOVING dupptr rc, lparam, 16 SetWindowPos hwnds(bkgdid), 0,rc, rc(1), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE SetWindowPos hwnds(mainid), 0,rc, rc(1), 0, 0, SWP_NOSIZE | SWP_NOZORDER return *LBUTTONDOWN if (ginfo_act=mainid) and (obj_bak(mainid)<0){objsel -1:obj_bak(mainid)=stat} PostMessageA hwnds(mainid), 0x0000A1, 0x0002, lparam gsel bkgdid,1 gsel mainid,1 if (obj_bak(mainid)>=0) {objsel obj_bak(mainid)} return *exit end
非編集モードにも対応しといた

XPでもたまにちらつくぐらいだからどこまで使えるか・・・



暇人

リンク

2013/3/24(Sun) 19:43:25|NO.53218

カーソルの動きがぎこちないので改善
> if v{break} //VBlank中
これを

if v or (r<(0.95*ginfo_wy2)){break} //VBlank中
に置き換え

これだけだと何も操作してなくてもコピーし続けて無駄に負荷が掛かるので
何か操作されたらGetRasterStatusのループに入るようにした方が良いかな



ろがー

リンク

2013/3/28(Thu) 03:22:16|NO.53293

返答有難う御座います

やはり相当めんどくさいことになってしまうのですね…。
ある程度妥協して我慢することにします。



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