Hatena::Groupnadesiko

雪乃☆雫のなでしこ日和

2016-11-21

一応解決・・・なのか??

| 04:02

 謎は解明しないけど、とりあえず親部品設定した後に、子ウィンドウを最大化すると、上手くいくようです。

 これはもちろん、位置の指定がってことではなく、ミニ画面にぴったり合わせて母艦表示できるようになったってだけのコトです。

#-----------------------------------------------------------
#窓ハンドル親設定の実験
テストとはフォーム母艦のタイトル=「親ウィンドウ」。
テストのタイトル=「子ウィンドウ」。
母艦の幅は200。母艦の高さは200。
テストの幅は200。テストの高さは200。
テストのスタイルは「枠なし」
窓ハンドル親設定((テストのハンドル),(母艦のハンドル))。
テストのXは0。テストのYは0。    # Xの位置がずれます
//テストを最大化。
母艦の可視はオン。テストの可視はオン。
テストのハンドルを窓ハンドルアクティブ。
テストを赤色画面クリア

●窓ハンドル親設定(子ハンドル,親ハンドル)=DLL("user32.dll","DWORD SetParent(DWORD, DWORD)")
#-----------------------------------------------------------

 というわけで、現状はこんな感じで、一応ミニ画面のところに母艦表示されるようになって、ちゃんとスクリーンセーバーの設定画面と連動して動くようにもなりました。

*プレビュー
  #二重起動の防止。
  プレビュータイトルとは文字列=「スクリーンセーバーサンプルのぷれびゅー画面」 #他とは容易にかぶらなそうなタイトルを指定のこと。
  窓列挙。一時=それ。
  一時の2で0からプレビュータイトルを表検索。
  もしそれ=-1でなければ、終わる。
  母艦のタイトルはプレビュータイトル

  #「スクリーン セーバーの設定」画面内のプレビューウィンドウ(ミニ画面)の情報を取得。
  PS=PWHの窓ハンドル内サイズ取得。
  Pxy=PWHの0,0を窓ハンドル画面座標計算。

  #母艦にプレビューウィンドウの位置サイズを設定
  母艦のスタイルは「枠なし」
  母艦のクライアント幅はPS¥0,2。
  母艦のクライアント高さはPS¥0,3。
  母艦のハンドルをPWHに窓ハンドル親設定。
  母艦を最大化。

  #プレビューウィンドウに実際に表示するもの
  母艦デスクトップ色画面クリア。
  「プレビュー」を表示。
  母艦の可視はオン
#-----------------------------------------------------------
# なでしこで作ったヤツじゃ無いウィンドウを親部品にしたり、子部品にしたりできる。
# なでしこライブラリ~ http://www26.atwiki.jp/isoroku_be/pages/66.html
●窓ハンドル親設定(子ハンドルを親ハンドルに)=DLL("user32.dll","DWORD SetParent(DWORD, DWORD)")
#-----------------------------------------------------------

 がっ・・・

 やっぱりこれだけじゃダメだったんです。

 子ウィンドウにしたら、「スクリーン セーバーの設定」画面が閉じて、母艦の親部品も無くなったら終了するかと思ったら、しなかった。

 最初の実験で、母艦を閉じたらテストも終了するのは母艦を閉じてるからであって、試しにメモ帳の子部品に母艦を設定してみたら、やっぱり終了しなかった。

 ・・・りゃそうだ;;;

 現状だと、ふつーに正しく「スクリーン セーバーの設定」をOKで終わらせても、表面上は見えなくなってもこっりとタスクに残っている。これはよろしくありません。

 「スクリーン セーバーの設定」ウィンドウが閉じたら、スクリーンセーバー終了させるようにしないとならないんだよね。

 しかし、力尽きたので今日のところはこれまで~;;;



 それにしても・・・

 「/s」と「/c」は、プログラムの最初に、コマンドライン¥1を設定することで、なでしこエディタだけで動作テストが出来るけど、プレビューだけは、スクリーンセーバーの設定の画面にインストールしないとお試し出来ないから、めんどくさー。

 実行ファイルつくって、.scrにリネームして、インストールして・・・って一連の動作を、なでしこさんにやってもらうようプログラムを作れば良いんだろうけど、なんかもう、それ自体が面倒なんだよぉ~(ダメダメ;;;)

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20161121

2016-11-20

プレビューは難しいよ!

| 22:44

 引き続き、スクリーンセーバーです。

 コンフィグで設定するほどのことは別に何も無いのだけど、設定ボタンを押しても何も動かないとゆうのはちょっとあれなんで、いつものバージョン情報でも表示させておくことにするw

#-----------------------------------------------------------
*コンフィグ
  ダイアログタイトルは「スクリーンセーバーサンプル」
  「{二重カッコ}スクリーンセーバー{改行}    ~実験中~{二重カッコ閉じ}{改行}   Version 0.00{改行}{改行}   by 雪乃☆雫」と言う。
  終わる。
#-----------------------------------------------------------

 忘れず最後は「終わる」で終わらせないと、単にOKを押してダイアログが消えても、プログラムは終わってないんで、スクリーンセーバーの設定ウィンドウの、ボタンの有効がオフになったような状態で止まってしまう。

 ふつーのアプリと違って、設定画面で何か設定したとしても、の後プログラム自体を終了させて、スクリーンセーバーは「/s」で再起動ってことになってるから、設定の内容はの都度iniか何かに保存しておかないとダメらしい。



 次に、プレビューのミニ画面なんですが、これがまあ、とんでもない曲者でした。

 HSPじゃ、何も考えずに出来たよーに思うんだけど・・・

 あれは、HSPのなかで、なんか勝手にどうにかしてくれることになっているんだろうね???

 取りあえず、いろいろ調べて分かったのは、起動オプション「/p」で起動する時は、「コマンドライン¥2」に、あのミニ画面のハンドルがはいるとゆうこと。

 なるほど、あのナゾの数字は、ーゆうことだったのね。

 のハンドルの、「窓ハンドル内サイズ取得」と「窓ハンドル画面座標計算」で、いちおうミニ画面のサイズと位置は取得できるんだけど・・・

 の前にっ! 絶対やらなきゃいけないことがありました。

 こいつ、「スクリーンセーバーの設定」画面が開く時に起動するだけじゃ無いんです。

 設定ボタンを押した時、プレビューボタンを押した時、それから、コンボボックスで別のスクリーンセーバーを選んだ時、いちいち終わらせるようにしないことには、次に復帰する時に、また「/p」オプションでスクリーンセーバーを再起動しやがるのです!

 「終わる」だけを入れてた時は良かったんだけど・・・あっというに沢山のスクリーンセーバーが密かに起動してて、「システムリソースがありません」かなんか怒られてしまった><

 こは、取りあえずこんな感じに。

#-----------------------------------------------------------
  #二重起動の防止。
  プレビュータイトルとは文字列=「スクリーンセーバーサンプルのぷれびゅー画面」 #他とは容易にかぶらなそうなタイトルを指定のこと。
  窓列挙。一時=それ。
  一時の2で0からプレビュータイトルを表検索。
  もしそれ=-1でなければ、終わる。
  母艦のタイトルはプレビュータイトル
#-----------------------------------------------------------

 起動してるヤツを終わらせると言うより、新しく起動した時に、自分と同じタイトルの窓が既にあったら、もう起動してると判断して起動ないことにする的な感じ。

 でも、なんかそれだけじゃダメな気がする・・・けど、一応エラーは出なくなった。


 さて・・・

#-----------------------------------------------------------
  #「スクリーン セーバーの設定」画面内のプレビューウィンドウ(ミニ画面)の情報を取得。
  PS=PWHの窓ハンドル内サイズ取得。
  Pxy=PWHの0,0を窓ハンドル画面座標計算。

  #母艦にプレビューウィンドウの位置サイズを設定
  母艦のスタイルは「枠なし」
  母艦のクライアント幅はPS¥0,2。
  母艦のクライアント高さはPS¥0,3。
  母艦の位置は「{Pxy¥0,0},{Pxy¥0,1}」

  #プレビューウィンドウに実際に表示するもの
  母艦デスクトップ色画面クリア。
  「プレビュー」を表示。
  母艦の可視はオン
#-----------------------------------------------------------

 こんなふうに、サイズと位置をミニ画面に合わせてつくってみたんだけど・・・

 ばっちり希望の場所に、小さい画面が表示されることはされるんだけど、よく考えたらこれでは全くダメで、スクリーンセーバーの設定画面が動いたり、他のウィンドウの下に隠れたりしたら、このちっちゃい母艦のままの場所に残ってしうまうのですよ~(´д`;

 親部品に設定出来るのは、なでしこで作ったヤツだけだしなー・・・と思っていたら、

http://www26.atwiki.jp/isoroku_be/pages/66.html

 ここに、なでしこで作ったヤツじゃ無いウィンドウを親部品にしたり、子部品にしたりする術がありました!

 素晴らしい!!!


 ところが・・・

 どーゆうわけか、位置の設定が上手くいかないんです。

 色々位置を言わせてみるとどうやら、Xの位置だけを設定した時はいいんですが、Yの位置を設定すると、反映されるのはYの位置だけで、Xの位置があらぬところにずれてしまう。

 これは一体!?!?

 むむむむぅ・・・

うぇいくうぇいく2016/11/21 20:37なでしこの部品の場合、内部でいろいろ情報持っていたり補正したりしているので、単純に親を設定してもうまくゆかない可能性が高いです。部品とAPIと併用するのは結構高難易度になります。
なでしこ内部・・・というより、その実行言語であるDelphiのライブラリのソースを読んで原因を探るぐらいじゃないと厳しいかと思います(なぜか、Delphiは製品にライブラリのソースが付属している。)
ライブラリも一応の考慮はされているので、うまくゆく時もあるので、その時は、それに乗ってしまうのも手ですが、うまくゆかないときは厳しいです。

スクリーンセーバー作成のpluginがあってもよさそうですが、なでしこの場合、フォルダに置いてあると必ず読み込まれちゃうんですよね・・・

雪乃☆雫雪乃☆雫2016/11/22 02:51うぇいくさま、ありがとうございます!
やはり、なかなか難しいことなのですね。
なにしろ、APIも借り物で、Delphiなんてとてもとても~>< ・・・という頭脳なので;;;
しかし、とりあえず、位置の指定ではなく全画面にすることで、なんとなくうまくいきそうな気配です☆

スクリーンセーバー作成のpluginがあったら嬉しかったですが、今となっては、スクリーンセーバー自体がもう、今さらな感じですもねー。
このミニ画面は、スクリーンセーバー的には一番どーでもよい機能なのですが、出来そう感が出てきたので、もう少し捨てずに粘ってみます・・

うぇいくうぇいく2016/11/22 23:39非常に長くて、大変申し訳ないのですが、以下のような感じで試してました。
よくわからないのですが、書かれている構成に似せて2ファイル構成です。

プレビュー時は、もらったハンドルが無効になるか非表示になったら終われば良い模様(それまでは本来の動作のようにアニメーションを繰り返しておく)

・・・あれ?プロセスを跨ぐとハンドル類は無効になったような気がするので、ドライバ側の実装は間違えているかも?(別プロセスに渡す場合は、相手プロセス用のハンドルを生成しないといけなかったような )

スクリーンセーバーテストドライバ.nako
--------------
'スクリーンセーバーテストドライバ

#窓ハンドル親設定の実験
プレビューエリアとはパネル。

母艦のタイトル=「親ウィンドウ」。
母艦の幅は300。母艦の高さは300。
プレビューエリアの幅は200。プレビューエリアの高さは200。
プレビューエリアのXは10。プレビューエリアのYは10。
母艦の可視はオン。プレビューエリアの可視はオフ。


プレビューボタンオンとはボタン
プレビューボタンオンの親部品は母艦
プレビューボタンオンのXは10
プレビューボタンオンのYは220
プレビューボタンオンのWは120
プレビューボタンオンのテキストは「プレビュー表示」
プレビューボタンオンのクリックした時は~
 プレビューエリアの可視はオン。
 「vnako.exe スクリーンセーバー.nako /p {プレビューエリアのハンドル}」を起動

プレビューボタンオフとはボタン
プレビューボタンオフの親部品は母艦
プレビューボタンオフのXは150
プレビューボタンオフのYは220
プレビューボタンオフのWは120
プレビューボタンオフのテキストは「プレビュー非表示」
プレビューボタンオフのクリックした時は~
 プレビューエリアの可視はオフ。
---------------------

スクリーンセーバー.nako
---------------------
'スクリーンセーバー
!変数宣言は必要
!変数初期化は必要

#-----------------------------------------------------------
●母艦設計
 母艦のタイトル=「親ウィンドウ」。
 母艦の可視はオフ

一時描画エリアとはイメージ
一時描画エリアの可視はオフ

プレビューハンドルとは整数
プレビューハンドルはコマンドライン¥2

HDCとは整数
HDCはGetDC(プレビューハンドル)

Sとは文字列
プレビュー幅とは整数
プレビュー高さとは整数
Sに16を確保
// 結果はSにLEFT,TOP,RIGHT,BOTTOMの構造体(全部long型)の内容が入る
GetWindowRect(プレビューハンドル, POINTER(S))
プレビュー幅は(Sの9を`LONG`でバイナリ取得)-(Sの1を`LONG`でバイナリ取得)
プレビュー高さは(Sの13を`LONG`でバイナリ取得)-(Sの5を`LONG`でバイナリ取得)

一時描画エリアの幅はプレビュー幅
一時描画エリアの高さはプレビュー高さ

(IsWindowVisible(プレビューハンドル)!=0)の間、
 // 一時描画エリアに描画する
 スクリーン描画(一時描画エリア)
 // 一時描画エリアの内容をプレビューのエリアに転写する
 // SRCCOPY=$00CC0020 元から先へ上書きコピー
 BitBlt(HDC,0,0,プレビュー幅,プレビュー高さ,一時描画エリアのハンドル,0,0,$00CC0020)
 0.05秒待つ

ReleaseDC(プレビューハンドル,HDC)

終わり

●スクリーン描画({グループ}描画対象)
 描画対象を赤色で画面クリア

●ReleaseDC(hWnd,hDC)=DLL("user32.dll",
"int ReleaseDC(
HWND hWnd, // ウィンドウのハンドル
HDC hDC // デバイスコンテキストのハンドル
)")

●IsWindowVisible(hWnd)=DLL("user32.dll",
"BOOL IsWindowVisible(
HWND hWnd // ウィンドウのハンドル
)")

●GetWindowRect(hWnd,lpRect)=DLL("user32.dll",
"BOOL GetWindowRect(
HWND hWnd,
LPRECT lpRect
)")

●BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop)=DLL("gdi32.dll",
"BOOL BitBlt(
HDC hdcDest, // コピー先デバイスコンテキストのハンドル
int nXDest, // コピー先長方形の左上隅の x 座標
int nYDest, // コピー先長方形の左上隅の y 座標
int nWidth, // コピー先長方形の幅
int nHeight, // コピー先長方形の高さ
HDC hdcSrc, // コピー元デバイスコンテキストのハンドル
int nXSrc, // コピー元長方形の左上隅の x 座標
int nYSrc, // コピー元長方形の左上隅の y 座標
DWORD dwRop // ラスタオペレーションコード
)")

●GetDC(hWnd)=DLL("user32.dll",
"HDC GetDC(
HWND hWnd // ウィンドウのハンドル
)")
----------------

雪乃☆雫雪乃☆雫2016/11/23 03:02はわわわわわ・・・
一人で勝手に騒いでいるだけでしたのに、こんなにまでして頂いて、本当にありがとうございます!!!
しかし~、今のところ中身が全く分からない~(泣)
MSDNながめて、目が回る~~~(@_@)
でも、今日苦労してなんだかんだした件や、どうしたら良いのか全く分からんと放置した一件が、IsWindowVisibleを使ったら、あっさり解決しそうということだけは閃きました;
こんなにAPIを使いまくらないとならないとは、プレビュー画面恐るべし・・・
ちょっとまた考え直してみます~。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20161120

2016-11-15

スクリーンセーバーにするよ!

| 16:48

 ・・・とゆうわけで、スクリーンセーバー

 スクリーンセーバーは、「/s」「/c」「/p」の三つの起動オプションで制御されていて、「/s」の時に、ふつーのスクリーンセーバーとして起動します。

 「/p」は、スクリーンセーバーの設定の中の、ちっちゃこいプレビュー画面を表示するためのもので、「/c」は、設定を押したら開くヤツだから、取りあえず無視することも可能。

 「/s」で起動する本体部分は、「枠なし」のフォームデスクトップいっぱいに表示して、マウスやキーのイベントで終わらすように設計すれば、OK。

#-----テスト用----------------------------------------------
//コマンドライン¥1は「/S」。
//コマンドライン言う。

#-----宣言--------------------------------------------------
OPとは文字列。        #起動オプション。

#-----------------------------------------------------------
#コマンドラインで取得した起動オプションで、動作を選択。
#-----------------------------------------------------------
OP=コマンドライン¥1の2文字左部分。  #起動オプション
もし、OP=「/p」または、OP=「/P」ならば、プレビュー。        #プレビュー(ミニ画面)
違えばもし、OP=「/c」または、OP=「/C」ならば、コンフィグ。    #コンフィグ(設定画面)
違えばもし、OP=「/s」または、OP=「/S」ならば、フルスクリーン。  #フルスクリーン(本体)
違えば終わる。
#-----------------------------------------------------------

*プレビュー
 終わる。

*コンフィグ
 終わる。

*フルスクリーン
  母艦について
    スタイルは「枠なし」
    クライアント幅はデスクトップW。
    クライアント高さはデスクトップH。
    位置は「{0},{0}」。
    キー押した時は~終わる。
    クリックした時は~終わる。
#-----------------------------------------------------------
#スクリーンセーバーの本体プログラム。
#-----------------------------------------------------------
  母艦デスクトップ色画面クリア。
  母艦の可視はオン
#-----------------------------------------------------------

 取りあえずこんな感じ?

 起動する場所によって、コマンドライン起動オプションが、大文字だったり小文字だったりするのはやめて欲しい・・・

 こにきづくまで、無駄に頭を悩ませてしまった(涙)

 でもこれで、本体部分を書き換えたら、それっぽく動くっぽい~♪


 だけど、ホントはスクリーンセーバーって、マウスクリックじゃなくって、マウスをチョコット動かしても復帰するものだよね。

 「マウス移動した時」のイベントがあるんだけど、これ終わるを設定すると、どんなにマウスを動かさないよう気をつけても、ってか、マウスには触れずに[F5]で起動させても、っこーで終了してしまうんだよね。

 どうやらこのイベントは、マウスの移動を検出するんじゃなくて、マウスがの部品の上にある中発生し続けているイベントらしい~。むむむ。

 ・・・いろいろ考えた結果、

#-----------------------------------------------------------
#宣言
初期マウスXとは整数=-1。初期マウスYとは整数=-1。
#-----------------------------------------------------------
#母艦について
    マウス移動した時は~
      もし、(初期マウスX=-1)かつ(初期マウスY=-1)ならば、
        初期マウスX=母艦のマウスX。初期マウスY=母艦のマウスY。
      違えば、(初期マウスX=母艦のマウスX)または
      (初期マウスY=母艦のマウスY)でなければ、終わる。
#-----------------------------------------------------------

 こうなった。

 画面の座標は、0,0から始まるので、しょっぱな変数の範囲外のマイナスの値を与えておけば、いっとう最初にイベントが呼ばれた時が分かるので、それにマウス位置の初期値を記憶し、2目以降からはの値と比較して、起動時とマウスの位置が変わったかを判定する。


 それから、マウスカーソルを消す術が、

http://www26.atwiki.jp/isoroku_be/pages/122.html

 ここにありました!

 いや~、世の中の賢い方々のおかげでWindowsAPIも使えて、ありがたや~。

 引用元を見ると、過去にもスクリーンセーバーを作りたい人がいたっぽいケド、もうリンクが切れてる(´・ω・`)


 だいたい、時はもう、スクリーンセーバーは流行らないよね。も液晶、焼き付かないし(爆)

 省エネで、スクリーンセーバーなんか表示するよか、画面暗くしたりスリープにしたりする時代だもね~。

 ワタシは、結構好きなのにさー。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20161115