• ベストアンサー

WindowsAPIでの…

WindowsAPIで作ったウインドウで あるアクションをするとあるオブジェクトが作成され(?) それが描画され、それ以降はそれを削除しない限り その部分をクリックしたり、ドラッグしたりすると何らかの操作が出来る。 という、さまざまなアプリケーションの基本的とも言えそうな部分は どのようにして作るのでしょうか? これもまたCreatWindowExを使って全部やってしまうのが基本なのでしょうか…?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.8

 こんばんは。補足頂きました。  リージョンは、ウィンドウを変形させたい時に使用します。四角形のままで良いのならば、無理に使う必要は無いと思います。  取り敢えずはC++/CLI Netの方で、どれ位まで出来るのかを、一度入念に調べまわした方が良いかもしれません。  私もC++/CLI Netに関しては、GUI等に関しては、まだ突っ込んで使用してはいないので、未知です(ただ、出来るとは思う)。  他回答者様も挙げられているDirectX系は強力ですが、その初期化ステップたるや、相当な労力を要します。一応DirectInputに関してはキーボードは使ってきたのですが、マウスは使った事がないので私の口からは如何とも明言できない状態です。  ただ、DirectInputのキーボード、マウス等の初期化は非常に似ています。  取り敢えず、サイトでもサンプルは良く出回っているので、情報には困らないと思います。取り敢えずはお膳立てをするのが大変と言う事です。  マウスのキャプチャはウィンドウプロシージャ内でケリを付けれますが、プロシージャ内の処理が結構大変です。  WM_LBUTTONDOWN等でSetCapture()をかけると、以後、クライアント領域外であってもWM_MOUSEMOVEが呼ばれ続けるので此れを利用します。  WM_MOUSEMOVE内でLPARAMを使用せず、GetCursorPos()と言うマウスカーソルのスクリーン座礁をストレートに受け取れるAPIを繰り返し呼び出しながら、ポップアップウィンドウを其の位置にMoveWindow()でリアルタイムに動かし続けます。  WM_LBUTTONUP等でReleaseCapture()で解除します。マウスが放された下のウィンドウを検出する為にWindowFromPoint()を使用します。  後、マウスのキャプチャが強制解除されたりすると、WM_CANCELMODEのメッセージを受け取るので、此処でキャンセルされてしまった時の処理をします。  更に、移動している最中に絵が剥がれ落ちたり、チラついてしまっては、元も子も無いので、#7さんが言及されている通り、バックバッファーリングをする必要も出てきます。  尚、キャプチャでメッセージを受け取り続けるウィンドウは、空中に浮いたウィンドウ側ではなく、最初にクリックされたウィンドウです。  上記の方法でするのならば、「レイヤー」の画像で例ると、キャプチャでメッセージを受け取り続けているのは、半透明になった「レイヤー4」では無く、下にある「レイヤー4」の方だと思います。  恐らく其れは、オーナードローしているリストボックスコントロールなのでは?   だとすれば、リストボックスコントロールをサブクラス化しキャプチャをして、メッセージを受け取り続ける事になると思います・・・(当方が出した画像はそうやって処理しています)。  何れにしろ、茨の道だと思います・・・。

LongSecret
質問者

お礼

おおお! なるほど より具体的な「どうすればいいか」というあたり、ありがとうございます! 読んでみた感想としては、いずれにせよ「面白そう」だと思いました。 DirectXの本は既に持っていてある程度読んでいたので、「DirectSoundの初期化」よりかは幾分マシではないかな…? という認識があったので、どのみちそれは使うという前提ですから 「そういう観点で見れば、それほど恐れる事でもないか」という気がします。ただ、最初の地点に到達するのが面倒そうには違いない、のですね。 少なくとも、色々やってはみたつもりなのですが .NETの自由度はプロっぽいレベルで考えるとおそらくそんなに高くないか、もし込み入った自由度を再現出来る場合があったとしても資料の発見に手間取りそうと思います(調べることの楽さでいけば、WindowsAPIの方がネット上にすでに大量の資料があるので上ですし) …というよりは、マネージ・ネイティブの速度差とかが念頭にあるので、ネイティブを意識して組みたいという思いも、あります。 頑張ってカスタマイズすれば出来るかも、という話し合いも以前あったのですが、どうせそうするなら自分で組む方が最小限で済むので省メモリだったり高速に組みやすそうですし…(GCに頼れない→全部解放処理を間違えずに書かないといけない。ので開発効率はどっちもどっちだと思いますが) >キャプチャはウィンドウプロシージャ内でケリを付けれますが、プロシージャ内の処理が やはり、結構いろいろ書かないと複雑な機能は実現できません…か。 とりあえず、先ほど初めてbmp画像をウインドウに表示させるところまでは行きました。 …資料に困りづらいため思ったよりも時間は要らないかもしれませんね。 >半透明になった「レイヤー4」では無く、下にある「レイヤー4」の方 最初勘でそっちだと思ってたのですが、思い違いか、と思いましたが、それでも出来るということですね? しかし DirectX…気になりますね。 参考にさせていただきながらWindowsAPIで組んでみて、DirectXでも組んでみて、色々比較してみるのがベストかもしれません。 ああ、そうなると結局一通りやるのか(苦笑) となれば 時間を節約したいので、分からない事があったらじゃんじゃん質問する、かもしれません。 その場合は、やはりよろしければ是非よろしくお願いします。 ありがとうございました!

その他の回答 (7)

  • okaki0429
  • ベストアンサー率16% (2/12)
回答No.7

「基本的には」というのは、単に私が知らないだけというのも考慮した回答です。(汗 画像を拝見させていただきました。 レイヤーXというのはWin32APIのボタンで実装できると思います。 ♪については、透明色の設定などが入ってきますので難しくなりそうですね。 こちらに関しては独自にウィンドウクラスを作ってもできると思いますが、普通の画像として扱い、BitBlt関数等を使って表示するという手法がいいかもしれません。 ただし、画面ちらつき防止のためダブルバッファという技術を使う必要があります。 DirectXは難しいですが、扱えるようになると便利かもしれませんね。 ただ、私はDirectX関連のことに関しては、DxLibライブラリでのゲームプログラミング経験があるだけなので、直接DirectXについてはわからないのですが・・・。 ということで私の意見は参考程度ということで聞き流してください。

LongSecret
質問者

お礼

ありがとうございます。 私の方が知識は少ないと思いますので、もしもそれが僅かな指標であっても、私は助かりますよ♪ 一つの方法のイメージが鮮明になったので、それだけでも有難いです。 「ダブルバッファ」を調べてみました。納得です。 BitBlt関数も調べます。 頑張って、早くいいものが作れるようになりたいです☆

回答No.6

 こんばんは。  思い浮かぶ限りは、レイヤードウィンドウをポップアップスタイルで作成して、マウスでキャプチャーする、と言った所でしょうか。  以下が参考になります。  http://azumaya.s101.xrea.com/wiki/index.php?%B3%D0%BD%F1%2FWin32%20API%2F%A5%EC%A5%A4%A5%E4%A1%BC%A5%C9%A5%A6%A5%A3%A5%F3%A5%C9%A5%A6%A4%F2%BA%EE%A4%EB  後ついでに、その楽譜の「♪」の部分も、CreateWindowExで作成出来ます。  以下のAPIを使って変形させる  http://msdn.microsoft.com/ja-jp/library/cc428592.aspx  ただ、手法としては他にもあるかと。  画像は研究の一環でして来た事ですが、(レイアードは使用していない)、殆どがCreateWindowExとビットマップとオーナードローです。

LongSecret
質問者

お礼

machongolaさんこんばんは。 ありがとうございます。 なるほど、やはりそれでもやる事は出来るんですか。 う~むしかし、同じような事をやるにしても本当に色々手段がありそうですね。 全部調べて回ってるのは結構大変そうですし…… ならば なにか…それぞれを比較したときの特徴、あるいは長所短所といった 指標になるものをご存じありませんか?

LongSecret
質問者

補足

透明化、確認してみましたよ! 次はリージョンを…(?)

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.5

>その場合も、プロシージャは必要になって、処理の部分をDirectXで適宜実装、という形になるのでしょうか? そういう実装もできますし、 DirectInputを使ってマウスの処理を行う方法もあります。 >つまりクリックイベント等は座標で全部制御してしまうという事なのでしょうか? DirectXの実装ではそうなります。 WindowsAPIで構築する場合はそうすることもできます。(ボタンのイメージも自前で表示する場合) 普通はボタン等を別のウインドウとし、 ボタンに対してメインウインドウとは別にWndProcを作り WM_LBUTTONDOWNを監視すれば、どの座標かは関係なくボタンが押された事はわかります。 >DirectXは別用途で使うことが確定 ただ全てのUIを描画を含めて自前で実装するのは結構大変なので、ゲームでもない限り普通は DirectXは使わず、OS(ウインドウズ)の用意してくれたものを使います。 (ちなみにDirectX SDKの中にはCustomUIというサンプルコードがありますが、これには ボタン、ラジオボタン、スクロールバー、コンボボックス、テキストボックス等、 基本的なコントロールが一通りDirectXで実装されています。ただサンプルとはいえMSのコードなので、 これを改変してコンパイルしたものを外部に公開してよいかまでは知りません。) 色々文章で回答しましたが、実際コーディングしないと実感できないと思います。

LongSecret
質問者

お礼

ありがとうございます。 今回のプログラムが完成したら次は3Dゲームを作ろうと思っていますので、どの道触れることにはなりますが、しかし、確かに十分使えるものは既存のものを…としようと思います。 今回は、作戦としては 1: .NET Frameworkに頼る 2: WindowsAPIに頼る 3: DirectXに頼る この優先順位になるかな…?と思っています。 うち1は結構触れてて、2は少しは触れてたので、大体のイメージはわきますが 3は未開ですので、ここからが面白くなるところ、かもしれませんね…? と言っても、基本的には時間節約のために上の方を使ってみて、それで 完全にイメージ通りに出来なければ……あるいはCPU使用量や高速化などを意識したい場合ほど下の選択肢が有効になり、またアプリケーションのオリジナル性が高くなる半面、制御が難しめだったりする…かもしれませんが その分得る物も大きいと思うので、本当に適宜選択する必要があるでしょう。 なお、別用途というのは音関係です。 これについては他にも選択肢が色々ありますので、出来るだけ多くに当たってみる必要があります。 DirectInputとWindowsAPIのメッセージ評価だと 性能的にはどちらの方がいいでしょうか? また、コーディングのし易さはどちらのほうがいいでしょうか?

  • FBL
  • ベストアンサー率0% (0/3)
回答No.4

下記の通り画像を用いての確認のため 別IDを使わせてください。 質問者です。 (もちろん、自身を良回答にする事はありません) また『Photoshop』および『Note Editor Pro』 というソフトに頼らせていただきます。 今まさにやりたいのは画像下のもので これはレイヤー4をクリックし、2と3の隙間にドラッグドロップする事で、レイヤーの表示位置を変えています。 これは、いかにもCreateWindowExでよさそうな感じがします。 対して上は、「単なる四分音符一個」です。 ・1の状態のところでクリックすると ・2のようにそこに存在が固定され ・後である状態でそれをドラッグすると(3) ・移動できる(4)というものです。 こんなに小さなものも、やはりCreateWindowExで作る事になるのでしょうか?

  • okaki0429
  • ベストアンサー率16% (2/12)
回答No.3

>これもまたCreatWindowExを使って全部やってしまうのが基本なのでしょうか…? そのとおりです。 基本は HWND handle = CreateWindowEx([引数]...); とすることで新しいオブジェクト(ウィンドウ)を作ることができます。 今回の場合は、何かのアクションをすると作成ということなので、HWND型の配列を動的に確保するか、予めいくつか用意しておく必要がありますね。 例を出しておきます ※インデントは全角空白2文字です。 //---------------------------------------------------------- #include <windows.h> #define OBJ_MAX 100 LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {   static HWND obj[OBJ_MAX];   static int cnt;   switch (uMsg) {   case WM_COMMAND:     switch (wParam) {     case BUTTON:       if (cnt == OBJ_MAX) break;       obj[cnt++] = CreateWindowEx("省略します");       break;     }     break;   default:     return DefWindowProc(hWnd, uMsg, wParam, lParam);   }   return 0L; } //---------------------------------------------------------- CreateWindowEx()の処理は省略しましたが、 これはあるボタンが押されるたびにオブジェクトを新規作成するというものです。(100個まで) 質問者様の言語がCかC++かわからなかったので、一応どちらでも動くCで書きました。 Windowsプログラミングはここ数日していないので、コードに誤りがあるかもしれませんが悪しからず。(テストしていません) 基本的にはこのように書くので、あとは応用してください。 それでは、がんばってください!

LongSecret
質問者

お礼

ありがとうございます! 状況はだいぶ明瞭になりました。 いくつになるかはユーザーしだいになるので、動的確保で行こうと思います。 …ところが、「基本的には」という言葉を聞きますと、気になってしまいます。こんな場合でもCreateWindowEx()なのかな…? というのが、流石にこれでもそう…なのか? あるいは、そうでなくても出来るのか…? など、気になりましたので ちょっと画像を用いて確認させてください。 (どうもお礼や補足等では出来ないようなので、別IDにより回答欄を使わせてください。) 言語はC++/CLIです。なので、CでもC++でも構いませんよ。 (今はVC++2008のWindowsフォームアプリケーションを使っています。)

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.2

>オブジェクト ここでいうオブジェクトとはどのオブジェクトの事でしょうか? (WinAPIの::DeleteObjectで使うようなグラフィックオブジェクトの事?) それともボタンや何かキャラクタ等、抽象的なものでしょうか。 一般的にWinAPIだけで、グラフィック描画をするのは大変な事だと言われていますが、 DirectXを使って同じ事をするのと手間的には大して変わりません。 (ゲーム等のUI[ボタン、スクロールバー等]は全て自前で描画します。) もちろんもっと簡単な方法は色々存在します。 例えば単純にWindowを表示して、ボタンを表示して押すとメッセージが出る という事がやりたいだけならC#で書いた方が圧倒的に少ないコード量ですみます。 >という、さまざまなアプリケーションの基本的とも言えそうな部分は >どのようにして作るのでしょうか >これもまたCreatWindowExを使って全部やってしまうのが基本なのでしょうか…?? WindowsAPIに関して言えば ドラッグやクリック時にメッセージが発生しますので、その処理を適切に行うだけです。 WndProcでWM_LBUTTONDOWN(マウスの左ボタンが押された) の処理をすればいいですしどの座標で押されたかも取得できます。 http://www.kumei.ne.jp/c_lang/sdk/sdk_02.htm

LongSecret
質問者

お礼

ありがとうございます。 >ボタンや何かキャラクタ等、抽象的なもの そういう感じです。 どのみちDirectXは別用途で使うことが確定していますので、CPUに全部託すよりは、それでやっても問題ないです。 その場合も、プロシージャは必要になって、処理の部分をDirectXで適宜実装、という形になるのでしょうか? えっと… ウインドウにスクロールバーを配置し スクロール可能にします。 パネルみたいなものを、移動可能にします。 しかし! 確かに、一つ一つの動作が完了したら描画されている位置は確定します。 ということは、つまりクリックイベント等は座標で全部制御してしまうという事なのでしょうか?

LongSecret
質問者

補足

って、よく考えたら「どの道座標は必要になる」が正解ですよね? それを「ウインドウ側で制御するか」「オブジェクト側で制御するか」は、基本的にはオブジェクト側ではないかな…と思っていましたが、これは通常はそうでしょうか?

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

CreatWindowExはウィンドウを作るだけです。 ウィンドウ内で起きる様々な動作はウィンドウプロシージャで行い ます。ここで、画面描画とかドラッグ操作とかを自作します。 何のコンポーネントも使わないで自作すると、結構メンドウ臭い です。ウィンドウプロシージャはシステムが呼び出すので、関数の 型が決まっていて、その通りに作らなければいけません。 ここで何をするかは「プログラムの仕様」によって決まります。 サポートしないメッセージは規定処理に任せるか、0を返すだけで 何もしないとかプログラムします。

LongSecret
質問者

お礼

ありがとうございます。 その、「ウインドウで起きる様々な動作」 においてウィンドウプロシージャ内で 画面描画したものをドラッグ操作等出来るようにするのか 自分のコントロール用みたいなクラスをWNDCLASSEXで作って CreatWindowExでそれをそれ毎に作る…? という方法の2パターンを、大きく分けて思い描いていたのですが つまり 自由に操作したいものをウインドウ内に配置されるようにした場合はCreatWindowExを使うまでもなく出来るということでしょうか? 例えば 何かのメッセージを受け取った時に、動かせるパネルみたいなものを生成して(それ用のC++クラスを作っておいて)、その中に必要な情報を入れて、それをいじれるようにしたいのですが そういう場合は具体的にはどういうものを使えばいいのでしょうか?