アプリ版:「スタンプのみでお礼する」機能のリリースについて

開発環境は,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;
と変更したら,普通に終了メッセージが出ます。

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

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

A 回答 (2件)

 こんにちは。


 カーソルリソースをロードする時、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 …
    • good
    • 0
この回答へのお礼

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

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

お礼日時:2008/11/06 11:26

hcurがローカル変数のため、リソース解放するときにはハンドル失われているのでリソースリークする。


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

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

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

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

お礼日時:2008/11/06 11:29

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!