ドラッグ&ドロップ時にマウスポインタを変更するには?

解決


KANA  2008-10-23 11:48:46  No: 69148  IP: 192.*.*.*

はじめまして。
開発環境は,Visual C++ 2008で,簡単な電気回路シミュレータを製作しています。
今までは,Cのプログラミングで数値解析を行っていましたが,
GUIを駆使した自作のシミュレータを作ってみたいなと思いました。
回路シミュレータはSPICEやPSIMなどというものがありますが。

とりあえずツールバーを作り,そこに電源や抵抗などといったアイコンを作成しました。
このあとやりたいことは,このアイコンをクリックすると,マウスポインタがその図形に変わり,
フォームへドラッグ→ドロップすることで回路図を描きたいのです。
もちろんドロップした時点でマウスポインタは元に戻したいです。

もしヒントや参考になるサイト,参考書などがありましたら教えてください。
よろしくお願いします。

編集 削除
仲澤@失業者  2008-10-23 12:58:25  No: 69149  IP: 192.*.*.*

1.当該の素子のアイコン(*.icon)を作成
2.リソースに含める
3.LoadIcon()、LoadImage()等でロードし、
4.SetCursor()でロードしたアイコンをカーソルにする

のようにやります。。

編集 削除
夏みかん  2008-10-23 23:51:12  No: 69150  IP: 192.*.*.*

5.ドラッグ&ドロップの処理
6.SetCursor()でアイコンを戻す
と続きます。

編集 削除
KANA  2008-10-24 10:54:30  No: 69151  IP: 192.*.*.*

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

今まで,ヘッダとソースファイルしか作ったことがなかったので,
「リソースに含める」という表現など,
リソースファイルの使い勝手がいまいちわかりませんが,
1〜6の手順を参考に頑張ってみます。
少々時間をください。

編集 削除
Blue  2008-10-24 12:16:10  No: 69152  IP: 192.*.*.*

開発環境を明確にしておいたほうが適切なアドバイスがもらえますよ。

MFCや.NET Framework(C++/CLI)であれば案外簡単に設定ができたりしますし。

環境明記例
Windows Vista/VC++2008 MFCアプリケーション

編集 削除
KANA  2008-10-24 13:05:09  No: 69153  IP: 192.*.*.*

>>開発環境を明確にしておいたほうが適切なアドバイスがもらえますよ。

なるほど,確かにプロジェクトの種類が色々あって迷いました。
以下のような環境です。

Visual studio 2008 Professional Edition/
Visual C++ 2008/Windows Vista/

プロジェクトは,
[プロジェクト]→[Visual C++]→[CLR]→[Windowsフォームアプリケーション]というのを選びました。
.NET Framework 3.5のようです。

編集 削除
Blue  2008-10-24 13:31:51  No: 69154  IP: 192.*.*.*

>[プロジェクト]→[Visual C++]→[CLR]→[Windowsフォームアプリケーション]というのを選びました。
正直なところ、C++/CLIの参考資料はあまりないです。
(C#やVB.NETの記述を見て変換するぐらいしかない)
→荊の道になる。
  C++/CLIの入門書を読みこなしてからじゃないと厳しそう。

とありあえず、ドラッグ対象のGiveFeedback イベントでアイコンを変更できます。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.givefeedback(VS.80).aspx

C#,VB.NETの参考になるサイト
http://dobon.net/vb/dotnet/control/draganddrop.html

編集 削除
KANA  2008-11-04 17:52:43  No: 69155  IP: 192.*.*.*

ネコでもわかるWindowsプログラミングをひと通り読みました。
ツールバーをtoolbar.bmpとして,ボタンをいくつか作成しました。

とりあえず最も左端のボタンを,ID_Vと定義して,
ボタンをクリックしたときに終了コマンドが出るようにしました。
以下はソースの一部分です。

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
  int id;
  
  INITCOMMONCONTROLSEX cc;
  static HWND hTool;
  static HMENU hMenu;

  switch (msg) {
    case WM_CREATE:
      hMenu = GetMenu(hWnd);
      cc.dwSize = sizeof(INITCOMMONCONTROLSEX);
      cc.dwICC = ICC_BAR_CLASSES;
      InitCommonControlsEx(&cc);
      hTool = MyCreateToolbar(hWnd);
      break;
    case WM_COMMAND:
      switch (LOWORD(wp)) {
//電源
        case ID_V:
          SendMessage(hWnd, WM_CLOSE, 0, 0);
          break;

これはうまくいったので,次にカーソルに変更しようと思い,
以下のように中身を変えました。

case ID_V:
          HCURSOR hcur;

          hcur = (HCURSOR)LoadImage(NULL, ID_V, IMAGE_CURSOR, 0, 0, LR_SHARED);
          SetCursor(hcur);

という風にしたところ,ボタンをクリックしても特になにも起こりません…。

また,別途,リソースの追加でカーソルファイルを作って,
hcur = (HCURSOR)LoadImage(NULL, (LPCWSTR)IDC_V, IMAGE_CURSOR, 0, 0, LR_SHARED);
のようにしたところやはりうまく変更できません。

質問の仕方が稚拙かもしれませんが,
どこがおかしいのでしょうか。

編集 削除
とおりs  2008-11-05 20:31:02  No: 69156  IP: 192.*.*.*

まずはパッと見の突っ込みだけ。

ボタンのコマンドIDとしてID_Vを使ってるのに、カーソルのリソースIDでID_Vを
使ってるのはおかしくない?
多分LoadImage()でエラーになってると思う。
いきなり自作のカーソルじゃなくて、
  hcur = LoadCursor(NULL, IDC_WAIT);
  SetCursor(hcur);
ってやってみて砂時計のカーソルに変わるところから確認してみたらどう?

小ネタで、VC++のウォッチウィンドウで「@err, hr」っていうウォッチ式を
追加すると、ステップ実行した時に最新のGetLastError()の戻り値に対応する
メッセージが見れるから便利だよ。
例えば提示コードのLoadImage()をステップ実行すると「リソースが見つかりません」
みたいなメッセージが出るはず。

編集 削除
KANA  2008-11-06 10:32:07  No: 69157  IP: 192.*.*.*

Windows標準ボタンも読み込まれなかったんです。
カーソルが消失したりしました。

それで,いったん最初から作り直して,IDも自動的,デフォルトのままにしました。
そして,

case ID_BUTTON40001:
    HCURSOR hCur;
    hCur =  (HCURSOR)LoadImage(GetModuleHandle(0), 
                MAKEINTRESOURCE(IDC_CURSOR1), IMAGE_CURSOR, 0, 0, LR_SHARED);
    SetCursor(hCur);

のように,第一引数を変えたら理想の動作をしました。
ボタンをクリックしたら,自作のカーソルに形が変わりました。

また次の動作を考えますが,どうもありがとうございました。

編集 削除