06.タイトルバーのないウィンドゥをドラッグアンドドロップで移動
08.ウィンドウの外にマウスカーソルが移動できないようにする
16.標準命令でスクリーン座標系をウィンドウ座標系に変換するモジュール
17.標準命令でウィンドウ座標系をスクリーン座標系に変換するモジュール
18.アプリケーションキャプチャーモジュール (要llmod.as)
19.指定タイトルバーを点滅させるモジュール (要llmod.as)
20.アクティブなウィンドウのタイトルテキストを取得するモジュール (要llmod.as)
21.指定ウィンドウのタイトルテキストを設定するモジュール (要llmod.as)
22.指定ウィンドウ操作を無効・有効化するモジュール (要llmod.as)
23.指定ウィンドウ操作の初期化モジュール (要llmod.as)
24.指定ウィンドウの閉じるボタンを無効化にするモジュール (要llmod.as)
01.ディスプレイの中央に移動する
ウィンドゥを移動させるには「width」を使います。
中央に寄せるために必要になるのは「ウィンドウサイズ」と「ディスプレイサイズ」です。
ディスプレイの中央点は(dispx/2,dispy/2)です。
すなわちココにウィンドウの中央点が来るように設定すれば必然的にウィンドゥが中央になります。
具体的にどうするかと言うと、
ウィンドウの幅の半分をディスプレイ中央より左に
ウィンドウの高さの半分をディスプレイ中央より上に移動します。
(例)ウィンドゥを中央に移動
width dispx-640/2,dispy-480/2 ; ホントはカッコでくくるがHSPは左から計算するのでなくてもよい
stop
02.フルスクリーンで表示する
フルスクリーンにするにはタイトルバーのないbgscrでウィンドウを作成します。
bgscrはウィンドウID0と1(できるが禁止)には使用できないので、ID2以降で作成してください。
(例)フルスクリーン表示
gsel 0,-1
bgscr 2,dispx,dispy,0,0,0
color
boxf
color 255,255
pos dispx-100/2,dispy-10/2 : mes "終了は「ALT+F4」です"
stop
03.マウスカーソルにまとわりつく
マウスカーソルのディスプレイ上の座標をリアルタイムに監視し、その位置にウィンドゥを配置すれば、
あっという間に「マウスカーソルアクセサリー」ができちゃいます。
マウスの座標と同じようにウィンドウ位置が変わるので×ボタンや最小化ボタンは押せませんね。
またデザイン的にもタイトルバーはないほうがいいと思うのでbgscrを使いましょう。
終了は「ALT+F4」キーです。実際使用する場合もこう言った終了の仕方を記述をしましょうね。
(例)マウスカーソルアクセサリー
gsel 0,-1
bgscr 2,100,20,0
pos 2, 0 : mes "終了はALT+F4"
repeat
ginfo 0 ; ディスプレイ上のカーソル座標
mx=prmx
my=prmy
width ,,mx+32,my
wait 1 ; 必ずウエイトを掛けること
loop
04.タイトルバーの高さを求める
ウィンドウを操作する時に、タイトルバー(キャプションバー)の高さを知る必要があることもあります。
DLLを使って高さを知るのが1番確実ですが、その為だけにDLLを使うと言うのであればスマートではありません。
標準命令だけでおおよそは求めることができます。
まずginfoのタイプ5でウィンドウの枠線を含めた大きさを求めます。
高さは枠線とタイトルバーも含まれるので、高さではなく横幅を使います。
この取り出したprmxからwinx(枠線を含まない)を引いてやれば2本分の枠線の太さ(固定ウィンドウ)が求まります。
そして初めのginfoのprmyからwinyと2本分の枠線(上と下の2本)を引いてやればタイトルバーの高さとなります。
あくまでこれは独自のやり方であって正確なものかは定かではないです・・・。
(例)タイトルバーの高さを求める
screen 0,300,200,0
ginfo 5
wx=prmx
wy=prmy
waku=wx-winx ; 2本分の枠線の太さ
bar=prmy-winy-waku
mes "タイトルバーの高さは"+bar+"です"
stop
05.マウスが近付くとウィンドウを非表示にする
最前面で常駐させるツールを作ると、そのウィンドウの下にある部分は当然見えません。
それでいちいちウィンドウを動かさなければならないようでは、かえって邪魔なソフトになりかねません。
こう言う場合は、カーソルが作成したウィンドウ上にくるとウィンドウを非表示にして、
ウィンドウ位置のある位置から外れると再び表示させるようにするとよいと思います。
ここでのポイントは「現在ソフトがスクリーン上のどの位置にあるか」「カーソルはどこか」ですね。
それともう1点。カーソルがタイトルバーの上に来ても消えないようにするのもポイントでしょう。
そうしないと移動はおろか×ボタンで終了できなくなってしまいます(ALT+F4はいけるけど)。
タイトルバーの高さは04の方法で求めたいと思います。
(例)マウスカーソルがウィンドウ上(タイトルバー除く)に来た時だけ非表示にする
screen 0,300,200,0
ginfo 5 ; 枠線を含めたウィンドゥサイズを求める
wx=prmx
wy=prmy
waku=wx-winx
bar=prmy-winy-(waku/2) ; 上側の枠線分の高さは必要な為、1本分だけ引く
repeat
ginfo ; スクリーン上でのマウスカーソルの座標を求める
mx=prmx
my=prmy
ginfo 2 ; ウィンドウの左上端の座標を求める
wx=prmx
wy=prmy
ginfo 3 ; ウィンドウの右下端の座標を求める
sx=prmx
sy=prmy
if mx>=wx&(mx<=sx)&(my>=(wy+bar))&(my<=sy) : gsel 0,-1 : else : gsel 0,2
wait 1
loop
06.タイトルバーのないウィンドゥをドラッグアンドドロップで移動
マウス左ボタンが押されて、マウス座標(スクリーン座標)が変更されたらウィンドウもあわせて動かしてやれば、
タイトルバーをつかんだときの様に動いてくれます。
ウィンドウ上のどの位置でボタンが押されているのか、どこにマウスを動かしたか、
この二つがわかればウィンドゥの移動先も決定します。
すなわち移動先は(マウスx座標-ウィンドウ上の押されたx座標,マウスy座標-ウィンドウ上の押されたy座標)です。
(例)ウィンドウを移動する
gsel 0,-1
bgscr 2,200,200,0,100,100
color : boxf
pos 10, 10 : mes "終了はALT+F4"
repeat
wx=mousex ; この値がウィンドウ上の押されたx座標になる
wy=mousey ; この値がウィンドウ上の押されたy座標になる
wait 1
stick k,256,1
if k&256 : gosub *move
loop
*move
ginfo 0
mx=prmx ; マウスの移動先x座標
my=prmy ; マウスの移動先y座標
width ,,mx-wx,my-wy
return
07.2重起動を防止する
ソフトが複数立ち上がってしまうのを防ぐために二重起動を防止させるやり方として簡単な方法を2つ紹介します。
(例1)ソフト起動時にファイルを作成し、終了時に削除する
exist exedir + "\\boushi.tmp" ; 実行ファイル
if strsize>=0 : end ; 既に起動している場合strsizeに1が入る
tmpfile=""
a href=../../../lecture/beginner19.htm#bsave>bsave exedir + "\\boushi.tmp",tmpfile,1
onexit *owari ; 終了時に必ず「owari」にジャンプさせる
stop
*owari
delete exedir + "\\boushi.tmp" ; 必ず終了時に削除させる
end
このサンプルのメリット・デメリットを説明します(メリットを青、デメリットを赤で記します)
標準命令だけでできますが、何らかの形で「boushi.tmp」が作成されなかった場合、
例えばCD-Rなどの書込み禁止場所の場合エラーが出てしまいます。
また、「不正な処理」等の強制終了されてしまって「boushi.tmp」が終了時に削除されなければ、
次回以降手動で削除しなければ立ち上げることができなくなります。
(例2)タイトルバーの文字で起動しているかをチェックする<要hspext.dll>
#include "hspext.as"
aplsel "SAMPLE" ;タイトルバーが「SAMPLE」から始まるウィンドゥがあるか調べる
if stat=0 : end
title "SAMPLE"
stop
こちらは「作成・削除ができずエラー」というものがなく、スクリプトの方も1に比べるトスマートです。
他の部分でhspext.dllが必要な命令を使っているならいいのですが、
使っていない場合、二重起動チェックの為にわざわざdllを同梱させねばなりません。
HSP2.6以上であれば、20のTIPSを使用することで回避できますけどね…。
また、例の場合「SAMPLE」から始まるタイトルバーのソフト(例えばSAMPLE VIEWER)を起動していると
1つしか起動していなくても条件式に当てはまってしまい終了してしまいます。
つまりチェックする文字列を含むウィンドゥが開いていると起動できないということです。
1番よい方法(確実に2重起動させる)は2重起動を防止する命令のあるDLLを使用することです。
08.ウィンドウの外にマウスカーソルが移動できないようにする
マウスカーソルの移動範囲を限定さすにはDLLを使用することで簡単に制限できますが
標準の機能だけでも実現すること可能ですのでやってみましょう。
(例)カーソルの移動を制限する
repeat
ginfo 2
wx=prmx
wy=prmy
ginfo 3
wx.1=prmx
wy.1=prmy
ginfo 0
if prmx<wx : mouse wx,prmy
if prmy<wy : mouse prmx,wy
if prmx>wx.1 : mouse wx.1,prmy
if prmy>wy.1 : mouse prmx,wy.1
wait 1
loop
09.画像でオリジナルカーソルにする
HSPウィンドウ内で画像を使用してカーソルの代わりに表示させて見ましょう。
03のやり方を応用すればディスプレイ上どこでも表示させることができますが、
標準命令ではカーソル以外の背景となる部分を透過することはできませんし、
カーソル座標にウィンドウを持っていくとHSPウィンドウをクリックすることとなりますので
マウスボタンを押しても効きません。
だからといってウィンドウをカーソルの上下左右に1ドット以上ずらすと、
元のカーソルが表示されてしまいますので実用は難しいでしょう。
(例)オリジナルカーソルに変更させる コチラをダウンロードしてからテストしてください
buffer 2
picload "gcur.bmp"
gsel 0
gmode 2
mouse -1
repeat
redraw 0
color 255,255,255
boxf
pos mousex,mousey : gcopy 2,0,0,32,32
redraw
wait 1
loop
10.ウィンドウがディスプレイ枠からはみ出さないようにする
ウィンドウが見えないところにはみ出すのが嫌という方は下記のサンプルを利用し、
ウィンドウ位置チェック+はみ出しを修正してみましょう。
(例)はみ出しを禁止する
#define sizex 200 ; ウィンドウ横幅
#define sizey 100 ; ウィンドウ高さ
screen 0,sizex,sizey,0
title ""
repeat
ginfo 2 ; ウィンドウ位置チェック
if prmx<0 : width sizex,sizey,0,prmy
if prmx+sizex>dispx : width sizex,sizey,dispx-sizex,prmy
if prmy<0 : width sizex,sizey,prmx,0
if prmy+sizey>dispy : width sizex,sizey,prmx,dispy-sizey
wait 1
loop
11.ウィンドウ最小化・元に戻す
ウィンドウを簡単に最小化・元に戻すことができます。
gsel命令を使用して同じようなこともできますが、タスクバーから消えてしまうのが欠点です。
下記のサンプルだと実際に最小化したときと同じくタスクバーに残ったままです。
(例)最小化・元に戻す
a=0
wait 100
objsend -28,$112,$F020,a,1 ; 最小化
wait 100
objsend -28,$112,$F120,a,1 ; 元に戻す
stop
12.D&Dでウィンドウサイズ変更
もうお気づきかもしれませんがobjsend命令でオブジェクトIDに-28を指定してやれば
オブジェクトではなく、自分自身(アプリケーションそのもの)を直接いじれます。
それを利用してウィンドウのサイズをD&Dで変更してしまいましょう。
ひとつ注意する点としてはじめにウィンドウサイズを最大にしておいてください。
width命令でも経験した人もいるかと思いますが初期サイズより大きくすると
ウィンドウ内が変に表示されてしまいます。
(例)ウィンドウサイズ変更
screen 0,dispx,dispy,0,dispx ; 目立たぬようスクリーン外で大きくしておく(^^;
width 640,480,100,50
a=0
*main
repeat
stick k,,1
if k==256 : objsend -28,$112,$f008,a,1 ; サイズ変更
wait 1
loop
goto *main
13.D&Dでウィンドウ移動パート2
06でウィンドウ移動をしましたがあまり好きな方法ではないという方のために
objsend命令にてタイトルバーのないウィンドウでも移動する方法を書いておきます(^^;
(例)D&Dで移動
*main
repeat
stick k,,1
if k&256 : objsend -28,$112,$f009,a,1
wait 1
loop
14.移動してもくっつくウィンドウ
どこに移動させても隣接するウィンドウのサンプルです。
ginfoで常にウィンドウ位置を取得しています。
(例)移動してもくっつく
dim wx,4
dim wy,4
wx=200,0,200
wy=300,0,200
screen 0,wx,wy
screen 2,wx.2,wy.2
repeat
ginfo 1
winid=prmx ; ウィンドウIDを取得
ginfo 2
if px.winid!=prmx|(py.winid!=prmy) : tmp=2-winid : gsel tmp : width wx.tmp,wy.tmp,prmx+wx,prmy : gsel winid : px.winid=prmx : py.winid=prmy
wait 1
loop
実行してみたらわかると思いますが、動かした方のウィンドウの右側にもうひとつのウィンドウがくっつきます。
そうではなく「ウィンドウID×は常に左側にしたい」というのであれば11行目を少し変えてください。
if文で判定させるため1行に入りきらなさそうだったのでこういう風にしてしまいました・・・。
よく見るとウィンドウ同士が少しかぶさっていると思います。
これはウィンドウサイズにウィンドウ枠サイズが入っていないためです。
ウィンドウ外枠にきっちりと隣接させたい場合は04の方法で枠サイズを求め、移動させる位置+枠サイズ分ずらしましょう。
15.自作製の別のEXEを標準命令だけで操作する
自作製の別に起動しているものを操作できないでしょうか?
hspext.dll等のDLLを使用すればアプリケーションキャプチャ命令で出来ますけど標準には搭載されていません。
しかし工夫次第でメッセージを渡すことが出来ますね。一時ファイルを作りそれが存在する時に処理をさせるとか…。
書込み禁止場所だと作成出来ずにエラーが出てしまいます。ここではクリップボードを利用しています。
コレはそういったエラーはありませんがクリップボードに元々データがあるとき上書きしてしまいます。
クリップボード内が文字列の場合(32000バイトまで)には下記の方法で何とか出来るかと思います
まずは「SAMPLESOFT2」をEXE化して「SAMPLESOFT1」を起動してください。
(例)連動ソフト「SAMPLESOFT2」
title "SAMPLESOFT2"
sdim clipboad,32
pos 0,-100 : mesbox clipboad,,,5
objsend 0,$302,zero,zero,1 ; クリップボード文字列のチェック
if clipboad!="StartsFromSamplesoft1" : dialog "SAMPLESOFT1からの起動ではありません"+clipboad : end
onexit *exit
pos 0,0 : mes "このファイル「SAMPLESOFT2」だけを終了してみてください"
stop
*exit
clipboad="AnEndOfSAMPLESOFT2"
objprm 0,clipboad
strlen len,clipboad
objsend 0,$b1,0,len,1 ; 送信文字列を再び選択する
objsend 0,$301,zero,zero,1 ; 連動ソフト終了の知らせ
end
(例)元となるソフト「SAMPLESOFT1」
title "SAMPLESOFT1"
sdim clipboad,32000
sdim sendmsg,32
pos 0,-100 : mesbox clipboad,,,5
objsend 0,$302,zero,zero,1 ; クリップボード内の文字列を退避
sendmsg="StartsFromSamplesoft1"
mesbox sendmsg,,,5
strlen terminus,sendmsg
objsend 1,$b1,0,terminus,1 ; 送信文字列を選択する
objsend 1,$300,zero,zero,1 ; クリップボードに文字列を送る
pos 0,0 : mes "連動ソフト「SAMPLESOFT2」を終了させてみてください"
exist "SAMPLESOFT2.exe"
if strsize<0 : pos 0,0 : mes "「SAMPLESOFT2」がこのプログラムと同じディレクトリに存在しません" : stop
exec "SAMPLESOFT2.exe"
repeat
wait 10
objprm 1,""
objsend 1,$302,zero,zero,1 ; 連動ソフトの終了チェック
if sendmsg="AnEndOfSAMPLESOFT2" : break
loop
mes "「SAMPLESOFT2」は終了しました"
strlen terminus,clipboad
objsend 0,$b1,0,terminus,1 ; 退避していた文字列を選択
objsend 0,$300,zero,zero,1 ; 退避文字列をクリップボードに戻す
stop
16.標準命令でスクリーン座標系をウィンドウ座標系に変換するモジュール
llmod.asにコレと同じことをする命令がありますが標準命令でもできそうでしたので試してみました。
p_scrwnd命令と同じく指定する配列変数の要素0にX座標,要素1にY座標を代入しておきます。
枠線やタイトルバーの高さ分の増減も必要なため4の方法で太さを求めています。
今となってはloadlib.dllがHSP内に組み込まれ、DLL不必要となったので意味のなくなったものですね。
(例)スクリーン座標系→ウィンドウ座標系
;************************** 概要説明 ************************
;
; scrtownd p1
;
; p1 : スクリーン座標系が入った数値変数
;
;***********************************************************
#module "coordinates"
#deffunc scrtownd val
mref p1,48
ginfo 5
wx=prmx : wy=prmy ; 枠線等も含めた全サイズを取得
ginfo 6
waku=wx-prmx/2 ; 1本分の枠線の太さを求める
wx-=waku+prmx : wy-=waku+prmy
ginfo 2
p1.0-=wx+prmx : p1.1-=wy+prmy
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
repeat
ginfo 0
ichi=prmx,prmy
scrtownd ichi
title ""+ichi+","+ichi.1
wait 1
loop
17.標準命令でウィンドウ座標系をスクリーン座標系に変換するモジュール
コレもllmod.asにコレと同じことをする命令がありますが標準命令でもできそうでしたので試してみました。
p_wndscr命令と同じく指定する配列変数の要素0にX座標,要素1にY座標を代入しておきます。
今となってはloadlib.dllがHSP内に組み込まれ、DLL不必要となったので意味のなくなったものですね。
(例)ウィンドウ座標系→スクリーン座標系
;************************** 概要説明 ************************
;
; wndtoscr p1
;
; p1 : ウィンドウ座標系が入った数値変数
;
;***********************************************************
#module "coordinates"
#deffunc wndtoscr val
mref p1,48
ginfo 5
wx=prmx : wy=prmy
ginfo 6
waku=wx-prmx/2
wx-=waku+prmx
wy-=waku+prmy
ginfo 2
p1.0+=wx+prmx : p1.1+=wy+prmy
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
repeat
ichi=mousex,mousey
wndtoscr ichi
title ""+ichi+","+ichi.1
wait 1
loop
18.アプリケーションキャプチャーモジュール (要llmod.as)
自作ソフトで別ソフトの監視が必要になったために利用したものをモジュール化したものです。
llmod.asを使用しているためHSP2.55ではloadlib.dllが必要です。2.6を使用している方にはあまり関係ありませんが。
このサンプルでは単に捕獲しているだけです。hspext.dllのように捕獲して何かができるわけではありません。
(例)電卓を制御
#include "llmod.as"
;************************** 概要説明 ************************
;
; captwin v1,n2
;
; v1=文字列型変数 : タイトルバーに入るテキスト
; n2=数値 : タイプ(0=起動しているかチェックだけ,1=アクティブ化,2=最小化,3=終了)
; 戻り値 : キャプチャー成功すればstatに1,失敗で0が入ります。
;
;***********************************************************
#module "capture"
#deffunc captwin val,int
mref lpwindowname,24
mref type,1
mref stt,64
stt=0
if lpwindowname="" : return
prm=0 ; NULL
getptr prm.1,lpwindowname
dllproc "FindWindowA",prm,2,D_USER@
prm=dllret@
if type<0|(type>3) : type=0
if type=0 {
if prm : stt=1
return
}
if type=3 {
if prm=0 : return ; コレがないと起動していない時HSPウィンドウが落ちる?
prm.1=$12 ; WM_QUIT
prm.2=0
prm.3=0
dllproc "PostMessageA",prm,4,D_USER@
if dllret@=0 : stt=0
} else {
dllproc "SetForegroundWindow",prm,1,D_USER@
dllproc "OpenIcon",prm,1,D_USER@
if type=1 : dllproc "CloseWindow",prm,1,D_USER@
if dllret@ : stt=1
}
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
file="電卓"
captwin file,0
if stat : mes "電卓は起動中です" : else : mes "電卓は起動していません"
wait 100
captwin file,2
if stat : mes "アクティブ化" : else : mes "アクティブ化に失敗しました"
wait 100
captwin file,1
if stat : mes "最小化" : else : mes "最小化に失敗しました"
wait 100
captwin file,3
if stat : mes "終了" : else : mes "終了に失敗しました"
stop
19.指定タイトルバーを点滅させるモジュール (要llmod.as)
27と同じようなもので、指定ウィンドウのタイトルバーを点滅させるものです。
p2の指定回数分p3の点滅間隔をあけて点滅します。間隔が短すぎると点滅しているようには見えません。
llmod.asを使用しているためHSP2.55ではloadlib.dllが必要です。2.6を使用している方にはあまり関係ありませんが。
使用APIも27とほぼ同じです。指定ウィンドウに注意を引かせたい場合等にご利用ください。
(例)電卓を起動し点滅させる
#include "llmod.as"
;************************** 概要説明 ************************
;
; flash v1,n2,n3
;
; v1=文字列型変数 : タイトルバーに入るテキスト
; n2=数値 : 繰り返し回数
; n3=数値 : 点滅間隔(ミリ秒)
;
;***********************************************************
#module "capture"
#deffunc flash val,int,int
mref lpwindowname,24
mref times,1
mref interval,2
repeat times
prm=0
getptr prm.1,lpwindowname
dllproc "FindWindowA",prm,2,D_USER@
prm.0=dllret@
if dllret@=0 : break
prm.1=1
dllproc "FlashWindow",prm,2,D_USER@
wait interval
loop
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
file="電卓"
exec "calc"
flash file,10,50
20.アクティブなウィンドウのタイトルテキストを取得するモジュール (要llmod.as)
HSPウィンドウのタイトルバー文字列を取得するのはもちろんHSP以外のも取得できます。
取得してどうするかは使用する人によっていろいろだと思います。ココでは34で利用しています。
ですのでココでは取得するモジュール部分だけの説明でサンプルはありません。
(例)タイトルバーテキスト取得
#include "llmod.as"
;************************** 概要説明 ************************
;
; titleget v1
;
; v1=文字列型変数 : 取得したタイトルテキストを代入する変数
;
;***********************************************************
#module "capture"
#deffunc titleget val
mref windowname,24
memset windowname,0,255
dllproc "GetForegroundWindow",prm,0,D_USER@
prm=dllret@
getptr prm.1,windowname
prm.2=255
dllproc "GetWindowTextA",prm,3,D_USER@
return
#global
21.指定ウィンドウのタイトルテキストを設定するモジュール (要llmod.as)
HSPだけでなく別ソフトのウィンドウタイトルも変更できるモジュールです。
あらかじめ指定となるウィンドウを動かしてもよいのですが33を利用しアクティブウィンドウを変更したいと思います。
ウィンドウタイトルを調べ処理しているソフトが多々ありますので
他ウィンドウタイトルテキストを変更するのはあまりよくないことかもしれませんのでお奨めしません^^;
アクティブウィンドウタイトル取得は33モジュールを一緒のところに入れてください。(当然#module,#globalは無用
注意を一点。タイトルテキストを変更しますが戻す処理を入れてません。戻したい場合は元の文字列を取得しておき、
別のウィンドウに変更されたら変更されている文字列を先ほどの文字列に変更してやればよいでしょう。
(例)アクティブウィンドウタイトルを変更する
#include "llmod.as"
;************************** 概要説明 ************************
;
; titleset "string","string"
;
; "string" : 設定する文字列
; "string" : 変更したいウィンドウタイトルテキスト
; stat=戻り値 : 0=正常終了,1=失敗
;
;***********************************************************
#module "capture"
#deffunc titleset str,str
mref dummy1,32
mref dummy2,33
mref stt,64
lpstring=dummy1
windowname=dummy2
prm=0
getptr prm.1,windowname
dllproc "FindWindowA",prm,2,D_USER@
prm.0=dllret@
getptr prm.1,lpstring
dllproc "SetWindowTextA",prm,2,D_USER@
if dllret@ : stt=0 : else : stt=1
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim titlename,256
sdim titlemsg,32
titlemsg="アクティブなタイトルバーです"
repeat
titleget titlename
titleset titlemsg,titlename
wait 5
loop
22.指定ウィンドウ操作を無効・有効化するモジュール (要llmod.as)
指定ウィンドウを停止し操作不能状態にするモジュールです。
タイトルバーテキストのものを指定ウィンドウとする様にしましたのでHSP以外のものでも利用できます。
無効化にしたままモジュールを利用したHSP側を終了させても無効化は解除されません。
HSPを終了させる時に指定ウィンドウを必ず有効化させるようにしてください。
(例)ウィンドウタイトルを指定させ無効・有効化させる
#include "llmod.as"
;************************** 概要説明 ************************
;
; enable s1,n2
;
; s1=文字列 : 有効・無効化させるウィンドウのタイトルテキスト
; n2=数値 : 制御フラグ(0:無効,1:有効)
;
;***********************************************************
#module "window"
#deffunc enable str,int
mref ttl,32
mref flag,1
ttlval=ttl
prm=0
getptr prm.1,ttlval
dllproc "FindWindowA",prm,2,D_USER@
prm=dllret@
prm.1=flag
dllproc "EnableWindow",prm,2,D_USER@
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim ttlstr,128
objsize 80,25
pos 100,50 : input ttlstr,200
pos 350,50 : button "無効化",invalid
pos 450,50 : button "有効化",valid
stop
*invalid
enable ttlstr,0
stop
*valid
enable ttlstr,1
stop
23.指定ウィンドウ操作の初期化モジュール (要llmod.as)
このTIPS以前にウィンドウ編でいくつかのHSPとは関係ない別ウィンドウを操作(キャプチャ)するモジュールをやってきました。
これから先もドンドン増やしていく予定なのですが、操作用に初期化する命令がなかったことに気づきました。
初期化といっても外見上が変化するというわけではなく、今から××を行う前に変数を1つ命令用にして、
今後その●●を操作するにはパラメータにその変数、若しくはID番号も一緒に渡すというパターンや、
変数を渡すことはないけど操作する前に1つ命令を通すことで操作対象をソレに変更するというものが初期化です。
コレだけでは何を言っているのか全く分からない方が大半でしょうから具体的な命令を掲げると、
操作対象を変更する為、命令を通すだけのパターンだと
objsel,
randomize,
snd,
gsel,
aplact,
comopen,
es_ini等々。
変数やID番号を渡すものだと
imeinit,
ll_libload,
noteselという命令。
dim,
sdimなんかもコレに当てはまるのです。
別にこの説明が理解できないと使えないというものではないです。そういったもの達がそうですよ、という説明です。
…で、言いたいのは、コレから先に指定ウィンドウを操作するときは、下記に紹介する命令を使ってくださいってことです。
操作対象ウィンドウのタイトルテキストを指定する形にしますので、テキストの直接指定、20等で取得してください。
このTIPSを使用し取得に成功すると、statに0が入り、失敗で1が入りますので、
指定したタイトルバーのウィンドウが既に起動しているかどうかのチェック用にも使えますね。
(例)二重起動防止
#include "llmod.as"
;************************** 概要説明 ************************
;
; captinit s1
;
; s1=文字列 : 操作対象にするタイトルテキスト
;
;***********************************************************
#module "capture"
#deffunc captinit str
mref caption,32
mref stt,64
dim handle,1
lpwindowname=caption
prm=0 ; NULL
getptr prm.1,lpwindowname
dllproc "FindWindowA",prm,2,D_USER
handle=stat
if handle : stt=0 : else : stt=1
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
file="二重起動防止テスト"
captinit file
if stat=0 : dialog "二重起動することは出来ません" : end
title file
stop
24.指定ウィンドウの閉じるボタンを無効化にするモジュール (要llmod.as)
22でウィンドウに対して無効化しましたが、今回は閉じる処理に対してだけ無効化にします。
閉じる処理というのは、右上に表示される「×」ボタン、タイトルバーアイコンクリックによるメニューの「閉じる」、
タスクバー内の右クリック時にポップアップする「閉じる」の3点だけです。
この方法だけではメニューバー内に「終了」メニューがあるものや「Alt+F4」や「強制終了」に対しては無効化は効きません。
また、無効化にしたままHSP側を終了しても対象ウィンドウの無効化は解除されませんのでご注意ください。
(例)閉じるボタンを操作
#include "llmod.as"
;************************** 概要説明 ************************
;
; closekill n1
;
; n1=数字 0:有効(1,2以外はすべて0とする)
; 1:無効(ボタンを灰色にする)
; 2:無効(外見は有効)
;
;***********************************************************
#module "capture"
#deffunc closekill int
mref flg,0
prm.0=handle
prm.1=0 ; FALSE
dllproc "GetSystemMenu",prm,2,D_USER
prm.0=dllret@
prm.1=$f060 ; SC_CLOSE
switch flg
case 1: prm.2=1
swbreak
case 2: prm.2=2
swbreak
default:prm.2=0
swend
dllproc "EnableMenuItem",prm,3,D_USER
if dllret@<0 : dialog "操作に失敗しました"
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
ttlname="無題 - メモ帳" ; OSによってはメモ帳のデフォルトのタイトルテキストが違うかもしれません
exec "notepad"
title ttlname
captinit ttlname ; 操作ウィンドウ初期化(37のTIPSを追加しないとココでエラーが出ます!)
objsize 100,25
combox index,100,"有効\n無効\n外見のみ有効"
button"実行",change
stop
*change
closekill index
stop
25.スクロール可能ウィンドウで初めからスクロールさせる
ウィンドウサイズより描画(クライアントエリア)サイズの方が大きい場合、スクロールバーが付加されます。
この「ウィンドウにスクロールバーがついた状態」では初め、左上(0,0)が見えていて、
右や下にスクロールさせられるようになっています。
左上側にタイトル等の見出しが来ることが多いので、通常はソレで問題がないのですが、
必ずしもそうとは限らず、中には別の所を表示させたいこともあるでしょう。
初めだけスクロールさせる、と限定させずにユーザーの意思とは別にスクロールさせたい場合にご利用ください。
(例)スクロールさせる
#define wx 320 ; 表示Xサイズ
#define wy 240 ; 表示Yサイズ
screen 2 , wx*2 , wy*2 , 0 , , , wx , wy
pos wx , wy : mes "ココはスクロールしないと見えない位置です"
mref bmscr , 67
bmscr.23 = wx ; X方向にスクロール
bmscr.24 = wy ; Y方向にスクロール
width wx , wy ; スクロールバー更新用のダミー
redraw ; 更新することで描画される
stop