こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

LoadImageとSetCursorについて

開発環境は,Visual studio 2008 Professional Edition/
Visual C++ 2008/Windows Vista/です。

Windowsプログラミングをしています。
猫でもわかる~を読んだ程度のレベルです。

現在,ツールバーは作成し,今後以下のような動作を実現させたいと考えています。
1)ボタンをクリックしたら,自作のカーソルファイル(cursor1.cur)を読み込んでその形にカーソルが変わる。
2)そのカーソルのまま,ドラッグ&ドロップし,フォームにその図形を置く(描く)。
3)図形を置いたら,カーソルを元に戻す。

このような流れです。

たぶん,LoadImage()でカーソルファイルを読み込み,
SetCursor()でカーソルの形を変えると思うのですが,
以下のようなプログラムを書いてもうまくいきませんでした。

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
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_BUTTON1:
HCURSOR hcur;
hcur = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_CURSOR1), IMAGE_CURSOR, 0, 0, LR_SHARED);
SetCursor(hcur);
//ドラッグ&ドロップ処理
//hcur = (HCURSOR)GetClassLongPtr(hwnd, GCL_HCURSOR); //カーソルを元に戻す
break;

一部分ですが,このような感じです。
ちなみにLoadImageの第一引数をNULLからhInst(HINSTANCE hInst;グローバル変数)に変えたところ,式を定義できないなどのエラーがでました。

ウインドウクラスの定義は,

//ウィンドウ・クラスの登録
ATOM InitApp(HINSTANCE hInst)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;//プロシージャ名
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;//インスタンス
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = TEXT("MYMENU");//メニュー名
wc.lpszClassName = szClassName;
wc.hIconSm = NULL;

return (RegisterClassEx(&wc));
}

以上の通りです。
ボタンを押してもうんともすんともいいません。

例えば,ウインドプロシージャのところを,
case ID_BUTTON1:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
と変更したら,普通に終了メッセージが出ます。

プログラム上どこがおかしいのか教えてください。
よろしくお願いします。

※字下げされずに読みづらくてすいません。

投稿日時 - 2008-11-05 15:52:27

QNo.4455593

困ってます

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

 こんにちは。
 カーソルリソースをロードする時、LoadImage()APIの第一パラメータに自分自身のモジュールハンドルを渡していないのが原因なのでは?

>>hcur = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_CURSOR1), IMAGE_CURSOR, 0, 0, LR_SHARED);
 ↓
>>hcur = (HCURSOR)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDC_CURSOR1), IMAGE_CURSOR, 0, 0, LR_SHARED);

 http://msdn.microsoft.com/ja-jp/library/cc364835.aspx

投稿日時 - 2008-11-05 16:48:29

お礼

第一引数がおかしいんじゃないかなとは思っていたのですが,
ご指摘の通りに変更したらうまく動作してくれました!

かなり試行錯誤しながら悩んでいたので本当に助かりました。
どうもありがとうございました。

投稿日時 - 2008-11-06 11:26:15

このQ&Aは役に立ちましたか?

5人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

Wr5

hcurがローカル変数のため、リソース解放するときにはハンドル失われているのでリソースリークする。
# 先に#1さんの指摘している部分の修正が必要ですが。
WM_COMMANDなどでSetCursor()しても、マウスカーソルを移動させるとウィンドウクラスに設定されたマウスカーソルへの再設定が行われる。
# クライスント領域内ではウィンドウクラスに登録したカーソルにOSが変更することで、ウィンドウのふちでのサイズ変更カーソルから戻せる。

とりあえず、リソースのハンドルを失わないようにstatic変数にするなどなんらかの対策を行いましょう。
WM_SETCURSORイベント時にSetCursor()しましょう。
# Spy++で監視しているとマウス移動と同時に大量に投げられています。

投稿日時 - 2008-11-06 00:16:58

お礼

まだ,フォームの外へカーソルが出たら戻ってしまったり,
完璧な動作とは言えませんが,ひとつ壁を越えることができた気がします。

ご意見を参考に,さらにつっこんだ対策を練ろうと思います。
ありがとうございました。

投稿日時 - 2008-11-06 11:29:22

あなたにオススメの質問