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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
1026
チャーくんすりガラス風のウィンドウ9解決


チャーくん

リンク

2015/10/26(Mon) 20:47:20|NO.72528

タイトルの通り、すりガラス(Windows 10のアクションセンター)っぽいウィンドウ
を作りたい…と思い、自ウィンドウの1px左上のハンドルを取得してキャプってブラー…
まではしたのですが、まぁ当然うまくいかないケースがありますよね。

「じゃぁウィンドウ表示する前にキャプればいーじゃん」って思うかもしれませんが、
リアルタイム(といっても2〜fpsでいいのですが)で更新されないと違和感があって…

なので、ウィンドウの周り1pxのハンドルを取得して、GetWindowでZオーダーの関係を取得して
奥から描画してぼかしをかける…という方法でやってみたのですが、なんか収拾がつかなく
なってしまったので、どのような方法があるのかを質問させていただきます。

下のやつは、左上1pxのスクリプトです。ちなみに一応ドラッグで移動するようにしてますが、
最終的には固定するつもりなので、移動のことは考えなくていいです。


#uselib "user32.dll" #cfunc GetWindowDC "GetWindowDC" int #func ReleaseDC "ReleaseDC" int,int #func GetWindowRect "GetWindowRect" int,int #func WindowFromPoint "WindowFromPoint" int,int #func GetParent "GetParent" int #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #module #deffunc gblur int p1 ;サンプル「gblur」のp2が無い版 gmode 3, ginfo_sx, ginfo_sy, 128 repeat p1 pos 1,0:gcopy ginfo(3):pos 0,0:gcopy ginfo(3),2,0 loop repeat p1 pos 0,1:gcopy ginfo(3):pos 0,0:gcopy ginfo(3),0,2 loop return #global dx=ginfo_dispx:dy=ginfo_dispy wx=400:wy=200 dim rect,4 buffer 1,dx,dy bgscr 0,wx,wy:hwindow.0=hwnd:title "終了はタスクバーかAlt+F4で":onclick gosub *move repeat windowfrompoint wx1-1,wy1-1 gsel 1 if hwndtarget!stat { if stat { hwndTarget=stat GetParent hwndTarget if stat!0 :hwndTarget=stat } color:boxf GetWindowRect hwndTarget, varptr(rect) xsrc=ginfo_wx1-rect(0):ysrc=ginfo_wy1-rect(1) hdcTarget = GetWindowDC(hwndTarget) BitBlt hdc,0,0,ginfo_winx,ginfo_winy,hdcTarget,xsrc,ysrc0x00CC0020 ReleaseDC hwndTarget, hdcTarget gblur 4 } gsel 0,2 redraw 0 color 36,36,36:boxf gmode 3,sx,sy,128:gcopy 1 redraw await 30 loop *move if wparam=1 :sendmsg hwindow.0,$000000A1,2,0 return
行数を減らしたため見づらいかもしれません…

EnumWindowsでデスクトップ上のハンドルをすべて取得した方が簡単な気がします。
…コールバック関数が使えればなぁ…

随分とワガママな質問でしかも長文申し訳ないのですが、
もしわかる方がいたら回答お願いします。



この記事に返信する


チャーくん

リンク

2015/10/26(Mon) 20:52:08|NO.72529

…すみません。なんか上のでは動かないっぽいので…

#uselib "user32.dll" #cfunc GetWindowDC "GetWindowDC" int #func ReleaseDC "ReleaseDC" int,int #func GetWindowRect "GetWindowRect" int,int #func WindowFromPoint "WindowFromPoint" int,int #func GetParent "GetParent" int #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #module #deffunc gblur int p1 ;サンプル「gblur」のp2が無い版 gmode 3, ginfo_sx, ginfo_sy, 128 repeat p1 pos 1,0:gcopy ginfo(3):pos 0,0:gcopy ginfo(3),2,0 loop repeat p1 pos 0,1:gcopy ginfo(3):pos 0,0:gcopy ginfo(3),0,2 loop return #global #define SRCCOPY 0x00CC0020 #define WM_NCLBUTTONDOWN $000000A1 #define HTCAPTION 2 dx=ginfo_dispx:dy=ginfo_dispy wx=400:wy=200 dim rect,4 buffer 1,dx,dy bgscr 0,wx,wy:hwindow.0=hwnd:title "終了はタスクバーかAlt+F4で" onclick gosub *move repeat wx1=ginfo_wx1:wy1=ginfo_wy1 windowfrompoint wx1-1,wy1-1 gsel 1 if hwndtarget!stat { if stat { hwndTarget=stat GetParent hwndTarget if stat!0 :hwndTarget=stat } color:boxf GetWindowRect hwndTarget, varptr(rect) sx=wx:sy=wy xsrc=ginfo_wx1-rect(0):ysrc=ginfo_wy1-rect(1) hdcTarget = GetWindowDC(hwndTarget) BitBlt hdc,0,0,sx,sy,hdcTarget,xsrc,ysrc,SRCCOPY ReleaseDC hwndTarget, hdcTarget gblur 4 } gsel 0,2 redraw 0 color 36,36,36:boxf gmode 3,sx,sy,128:gcopy 1 redraw await 30 loop *move if wparam=1 :sendmsg hwindow.0,WM_NCLBUTTONDOWN,HTCAPTION,0 return
これなら動くはずです。本当にすみません。



kanamaru

リンク

2015/10/26(Mon) 21:11:44|NO.72530

コールバック使えますよ。
2つ方法があります。
1.このhsptvのプラグイン・モジュール一覧でダウンロード出来るDLLを使う
2.この掲示板で公開されてるコールバックモジュールを使う
個人的には下がいいと思います。
というかすりガラスっぽいウィンドウを誰かソース公開してたような…



スペース

リンク

2015/10/26(Mon) 21:22:17|NO.72532

以前、Aero風のウィンドウを作ったことがあるのですが、結構お粗末です・・・
https://drive.google.com/file/d/0B9ot1K3av4xTakhKMmlBREw1NnM/view?usp=sharing

以下はウィンドウ背景を取得するスレです。
http://hsp.tv/play/pforum.php?mode=pastwch&num=53117



n

リンク

2015/10/26(Mon) 21:29:49|NO.72534

以前のスレにありました。

#include "hspcv.as" #define WM_NCLBUTTONDOWN $000000A1 #define HTCAPTION 2 // デスクトップ描画モジュール #module #uselib "User32.dll" #func SetWindowLong "SetWindowLongA" int, int, int #cfunc GetWindowLong "GetWindowLongA" int, int #func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int, int, int, int #cfunc BeginPaint "BeginPaint" int, var #func PaintDesktop "PaintDesktop" int #func EndPaint "EndPaint" int, var #func InvalidateRect "InvalidateRect" int, int, int #func UpdateWindow "UpdateWindow" int #cfunc GetDC "GetDC" int #uselib "Gdi32.dll" #func BitBlt "BitBlt" int, int, int, int, int, int, int, int, int #deffunc DrawDesktop selid = ginfo_sel if tempid == 0 : tempid = ginfo_newid bgscr tempid, ginfo_dispx, ginfo_dispy, 2, 0, 0 oncmd gosub *paint, 0xF/*WM_PAINT*/ hwnd_t = hwnd SetWindowLong hwnd_t, -20/*GWL_EXSTYLE*/, GetWindowLong(hwnd_t, -20/*GWL_EXSTYLE*/) | 0x80000/*WS_EX_LAYERED*/ SetLayeredWindowAttributes hwnd_t, 0, 0, 2/*ULW_ALPHA*/ gsel tempid, 1 InvalidateRect hwnd_t, 0, 0 UpdateWindow hwnd_t oncmd gosub *paint2, 0xF/*WM_PAINT*/ gsel selid BitBlt hdc, 0, 0, ginfo_dispx, ginfo_dispy, GetDC(hwnd_t), 0, 0, 0x00CC0020/*SRCCOPY*/ bgscr tempid, 1, 1, 2 gsel selid return *paint dim ps, 9 PaintDesktop BeginPaint(hwnd_t, ps) EndPaint hwnd_t, ps *paint2 return #global #include "user32.as" #define WM_VSCROLL $114 #define TBS_AUTOTICKS $1 #define TBM_SETPOS $405 #define TBM_SETTICFREQ $414 #define TBM_GETPOS $400 #uselib "dwmapi.dll" #func DwmIsCompositionEnabled "DwmIsCompositionEnabled" var //定義 #func DwmGetColorizationColor "DwmGetColorizationColor" int,int sound=50 gsel 0,-1 bgscr 12,550,350 buffer 1,ginfo_dispx,ginfo_dispy DrawDesktop cvbuffer 0,ginfo_dispx,ginfo_dispy //作業用CVバッファ buffer 2,ginfo_dispx,ginfo_dispy buffer 3,ginfo_winx,ginfo_winy gsel 1 cvputimg 0 //HSPバッファからCVバッファ0にコピー gsel 2 cvsmooth CV_BLUR,51,51,,0 //CVバッファ0をスムージング処理(数値は奇数限定) cvgetimg 0 //CVバッファ0からHSPウィンドウにコピー gsel 12 gcopy 2, ginfo_wx1, ginfo_wy1, ginfo_winx, ginfo_winy pos 100,100 winobj "msctls_trackbar32","", ,$50000000|$1, 200, 30 hTbar=objinfo_hwnd(stat) : objskip stat,1 ;ハンドルを取得 sendmsg hTbar, TBM_SETPOS, 1, sound ;デフォの位置(0~100) sendmsg hTbar, TBM_SETTICFREQ, 10 ;メモリの分割幅(0~100) oncmd gosub *vscroll,WM_VSCROLL repeat mx = ginfo_mx my = ginfo_my getkey click,1 if(MoveScroll==1){ MoveScroll=0 gsel 1 cvputimg 0 //HSPバッファからCVバッファ0にコピー gsel 2 BLUR_p1=sound BLUR_p2=sound BLUR_p1 | 1 //偶数だとエラーになるので奇数に BLUR_p2 | 1 cvsmooth CV_BLUR,BLUR_p1,BLUR_p2,,0 //CVバッファ0をスムージング処理(数値は奇数限定) cvgetimg 0 //CVバッファ0からHSPウィンドウにコピー } if (click == 1) && (clicko == 0) { omx=mousex omy=mousey } if(click==1&& mousex >=0 && mousex <=ginfo_winx && mousey >= 0 && mousey <=ginfo_winy/7 && MoveScroll==0){ //右クリ&& タイトルバー gpx=mx-omx gpy=my-omy MoveWindow hwnd, mx-omx, my-omy, ginfo_winx, ginfo_winy, 0 } gosub *Draw clicko=click await loop stop *vscroll if lparam=hTbar{ ;もし、トラックバーなら sendmsg lparam, TBM_GETPOS sound=stat MoveScroll=1 } return *Draw redraw 0 gsel 12 pos 0,0 gcopy 2, gpx, gpy, ginfo_winx, ginfo_winy gmode 4,ginfo_winx,ginfo_winy/7,70 gcopy 3,0,0,ginfo_winx,ginfo_winy/7 redraw 1 return

コピペです。
汚いです。



チャーくん

リンク

2015/10/27(Tue) 18:24:50|NO.72550

回答ありがとうございます。

>kanamaru さん
 あっ そういえばモジュール探してませんでした。
 今まですりガラスウィンドウのスクリプトはいくつも見たのですが…どれも違う感じです。

>スペース さん
 最初は僕もこういうのを作ってみたのですが、やはり向こう側の様子を更新しないと
 違和感が… なんで僕ってこういう所ばっかりこだわるんでしょうか…

>n さん
 だいぶ前のスレで壁紙が見えるツールがあって、それみたいにしようとも思ったのですが…
 やはりOSのGUIとの統一感を出すためには、自分のウィンドウのすぐ下が見えた方が
 いいのかな…とか思ってしまいます。
 あぁ、なんで僕ってこういう所(略

あと、Bitbltはストアアプリとかスタートメニューとかがキャプチャできないみたいです。

もうブラーかけるのやめて、タスクバーみたいにする方向を検討しています。
(Win10使ってる方は分かるかも知れませんが、タスクバーはブラーがかかってません)

ですが、もしこれから同じことで悩む人の為にも、できる限りやってみたいと思います。
もし良い方法をご存知の方はぜひ教えてください。

自分の周囲1pxにあるウィンドウのハンドルを取得する方法をもう一度試してみます。


…Aeroとは別にすりガラスっぽく表示できるようにならないかなぁ(ボソッ



kanamaru

リンク

2015/10/27(Tue) 18:35:52|NO.72551

ためしに検索して探してみたところ、
動作が遅いですが、
http://www.placeark.com/program_hsp_sample_file/sample_FrostedGlassWindow.hsp
というのを見つけました。



スペース

リンク

2015/10/27(Tue) 18:41:20|NO.72552

個人的に前からやりたいとは思っていたので、いい機会なので自分も少し挑戦してみようかな・・・



スペース

リンク

2015/10/27(Tue) 23:04:24|NO.72573

全てのウィンドウを個別に取得。ついでにデスクトップの壁紙も取得して表示するだけ。
うぅ〜ん重い・・・

#include "d3m.hsp" #include "hspcv.as" #define Bura cvputimg 0:cvsmooth CV_GAUSSIAN,21,21,,0:cvgetimg 0,1//ブラー #define WM_NCLBUTTONDOWN $000000A1 #define HTCAPTION 2 // デスクトップ描画モジュール #module #uselib "User32.dll" #func SetWindowLong "SetWindowLongA" int, int, int #cfunc GetWindowLong "GetWindowLongA" int, int #func SetLayeredWindowAttributes "SetLayeredWindowAttributes" int, int, int, int #cfunc BeginPaint "BeginPaint" int, var #func PaintDesktop "PaintDesktop" int #func EndPaint "EndPaint" int, var #func InvalidateRect "InvalidateRect" int, int, int #func UpdateWindow "UpdateWindow" int #cfunc GetDC "GetDC" int #uselib "Gdi32.dll" #func BitBlt "BitBlt" int, int, int, int, int, int, int, int, int #deffunc DrawDesktop selid = ginfo_sel if tempid == 0 : tempid = ginfo_newid Screen tempid, ginfo_dispx, ginfo_dispy, 2, 0, 0 oncmd gosub *paint, 0xF/*WM_PAINT*/ hwnd_t = hwnd SetWindowLong hwnd_t, -20/*GWL_EXSTYLE*/, GetWindowLong(hwnd_t, -20/*GWL_EXSTYLE*/) | 0x80000/*WS_EX_LAYERED*/ SetLayeredWindowAttributes hwnd_t, 0, 0, 2/*ULW_ALPHA*/ gsel tempid, 1 InvalidateRect hwnd_t, 0, 0 UpdateWindow hwnd_t oncmd gosub *paint2, 0xF/*WM_PAINT*/ gsel selid BitBlt hdc, 0, 0, ginfo_dispx, ginfo_dispy, GetDC(hwnd_t), 0, 0, 0x00CC0020/*SRCCOPY*/ bgscr tempid, 1, 1, 2 gsel selid return *paint dim ps, 9 PaintDesktop BeginPaint(hwnd_t, ps) EndPaint hwnd_t, ps *paint2 return #global #module ; ======== API 関数の定義 ======== #uselib "user32.dll" #func global FindWindowEx "FindWindowExA" sptr,sptr,sptr,sptr #func global GetWindowLong "GetWindowLongA" sptr,sptr #func global IsIconic "IsIconic" sptr #func global GetWindowText "GetWindowTextA" sptr,sptr,sptr #cfunc GetDC "GetDC" int #cfunc GetWindowDC "GetWindowDC" int #func ReleaseDC "ReleaseDC" int,int #cfunc GetForegroundWindow "GetForegroundWindow" #cfunc GetDesktopWindow "GetDesktopWindow" #func GetWindowRect "GetWindowRect" int,int #func GetClientRect "GetClientRect" int,int #uselib "gdi32.dll" #func BitBlt "BitBlt" int,int,int,int,int,int,int,int,int #define NULL 0 #define SRCCOPY 0x00CC0020 #define CAPTUREBLT 0x40000000 ; ======== 指定されたウィンドウのキャプチャ ======== #deffunc CaptureWindow //ウィンドウタイトルとウィンドウハンドルを取得。 //以下ページからコピペ //http://hsp.tv/play/pforum.php?mode=pastwch&num=32730 hwnd_=0 sdim wtitle, 129 dim Hwndls,129 WindowLs=0 repeat FindWindowEx 0 ,hwnd_, 0, 0 hwnd_=stat if hwnd_=0 : break GetWindowLong hwnd_, -8 if stat!=0 : continue GetWindowLong hwnd_, -16 if (stat & 0x10CA0000)!=0x10CA0000 and (stat & 0x16080000)!=0x16080000 : continue IsIconic hwnd_ if stat !=0 : continue GetWindowText hwnd_, varptr(wtitle), 128 if wtitle="":continue if wtitle!タイトル@:Hwndls.WindowLs=hwnd_:WindowLs+1//ウィンドウハンドルを記録し、カウンタに+1。ifは自分のウィンドウが表示されないように。 loop repeat WindowLs//ハンドル取得後にBitbltをやるとウィンドウのZ順が逆に成る為。わざわざ処理を分ける必要あり。 hwnd_=Hwndls.(WindowLs-cnt-1)//ハンドルを代入 //ウィンドウのサイズ取得 dim rect, 4//RECT構造体 GetWindowRect hwnd_, varptr(rect) sx = rect(2) - rect(0):sy = rect(3) - rect(1) ; 画像をコピー hdcTarget = GetWindowDC(hwnd_)//ハンドルからDC取得 BitBlt hdc, rect(0),rect(1), sx, sy, hdcTarget, 0, 0, SRCCOPY | CAPTUREBLT loop ReleaseDC hwndTarget, hdcTarget//デバイスコンテキスト解放 return エラーフラグ//正常終了時 stat = 0 #global win_x = 500 :win_y = 500//ウィンドウサイズ deskX=ginfo_dispx//デスクトップの deskY=ginfo_dispy//X、Yサイズを取得 cvbuffer 0,win_x,win_y//CVバッファ初期化 buffer 3,deskX,deskY:DrawDesktop//デスクトップの壁紙。nさんが貼ってくれたスクリプトから流用。 buffer 1,deskX,deskY//壁紙とウィンドウを合成 buffer 4,win_x,win_y//テンポラ。 bgscr 0,win_x,win_y:gsel 0,2//メインウィンドウ font "メイリオ",25,17 タイトル="擬似Aero" title ""+タイトル repeat mx = ginfo_mx//何度か使うので、変数に現在のスクリーン上のマウス位置を記録 my = ginfo_my gsel 0 gwposx=ginfo_wx1 gwposy=ginfo_wy1 if ginfo_act=0:getkey 左クリック,1:else:左クリック=0 getkey ブラーフラグ,17//Ctrlでブラーあり getkey esc,27:if esc=1:end//escで終了 if 左クリック = 1 and 左クリックbac = 0 or cnt = 0 :win_mx=mousex:win_my=mousey//ドラック処理 if 左クリック = 1:{ win_pos_x = mx-win_mx : win_pos_y=my-win_my if win_pos_x<=0:win_pos_x=0 if win_pos_y<=0:win_pos_y=0 } redraw 0 gsel 1 pos 0,0:gcopy 3,0,0,deskX,deskY//デスクトップの壁紙を描画して CaptureWindow//ウィンドウを描画 gsel 4//ブラーを掛ける処理。全体にかけると重い為、必要最低限の範囲 pos 0,0:gcopy 1,gwposx,gwposy,win_x,win_y//でもcvgetimgが枠なしウィンドウに対応したい無いっぽいので一旦bufferに描く必要あり。 if ブラーフラグ=1:Bura//ブラーを掛ける gsel 0 pos 0,0:gcopy 4,0,0,win_x,win_y//メインウィンドウにcopy //情報表示 情報=""+d3getfps()+"fps\nwin_pos_x:"+win_pos_x+"\nwin_pos_y:"+win_pos_y+"\nwin_mx:"+win_mx+"\nwin_my:"+win_my+"\ncnt:"+cnt+"" color 255,255,255 pos 99,0:mes 情報 pos 101,0:mes 情報 pos 100,-1:mes 情報 pos 100,1:mes 情報 color 0,0,0 pos 100,0:mes 情報 //情報表示 左クリックbac=左クリック//1フレーム前の情報を記録 line 0,0,0,500:line 0,0,499,0:line 0,499,500,499:line 499,0,499,500//見やすいように、ウィンドウに枠を表示。 redraw 1 if 左クリック=1:width ,,win_pos_x,win_pos_y//ウィンドウ位置を変更。redrawの間にwidthを書くとラグが増えるので、最後の方に書いたほうがいいかも? mx_bac=mx:my_bac=my await 17-(cnt\3=0) loop



チャーくん

リンク

2015/10/28(Wed) 20:33:37|NO.72589

>kanamaru さん
 このスクリプトも見てみたのですが、どうやらレイヤードウィンドウをキャプチャしない
 方法みたいでこちらでは上手く動きませんでした。
 なんでレイヤードウィンドウもキャプチャするようにしたんだろ…
>スペース さん
 ス、スゴい…
 なんだか感動してしまいました。
 ロースペックな環境でも文字などの背景としては十分な速度が出ていました。

回答ありがとうございました。解決です!



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