カーソルが特定のコントロールの上にあるときにカーソルを変更する場合は、そのコントロールのウィンドウのメッセージを処理する必要があります。このメッセージを受信すると、SetCursor
関数を呼び出して、表示すべきカーソルを設定します。この関数は、単一のパラメータ、つまりカーソルへのハンドル(HCURSOR
)をとります。これに関する詳細については、Raymond Chenの記事を必ず読んでください。"What is the process by which the cursor gets set?"
SetSystemCursor
の機能は一切使用しないでください。その機能は、のグローバルカーソル設定を変更する方法を提供します。マウスコントロールパネルで同じカーソル設定を変更することができます。デスクトップをカスタマイズしたい場合は、変更する必要があります。アプリケーションはそれだけを残すべきです。アプリケーションのコントロール上にファンキーなカーソルを表示したい場合は全く問題ありませんが、ではないシステム全体の矢印カーソルをファンキーなものに置き換えても問題ありません!
私たちは実際にSetSystemCursor
を呼び出す正しい方法について心配する必要はありません。だから、カーソルの読み込みを見てみましょう。あなたは既にLoadCursorFromFile
関数を見つけました。実際、この名前はその名前が示すとおりです。 CURファイルへのパスを与え、カーソルとしてハンドルを渡してカーソルを右にロードします(HCURSOR
)。しかし、テストの目的以外では、LoadCursorFromFile
を使用しているとは思わないでしょう。どうして?あなたのアプリケーションと一緒にCURファイルを配備する必要はないからです。そのファイルが削除されるか、含まれていない場合、アプリケーションは動作しなくなります。
代わりに、カーソルをアプリケーションのバイナリに直接リンクする必要があります。幸いにも、Windowsはバイナリのリソースの一部としてこれを行う方法を提供します。これまでにWindowsプログラミングをしたことがあるなら、あなたは確かにリソースファイルを見たことがあります。 RCファイルに、ICOファイルへのパスを指定するカーソルリソースを追加することができます。リソースコンパイラは残りの処理を行い、そのカーソルをEXEに直接埋め込みます。これで、実行時に脆弱なパスに頼る必要がなくなりました。LoadCursor
を呼び出してリソースからカーソルをロードするだけです。 (すべてのリソースResource.hを呼ばれるヘッダ・ファイルに定義された数値IDを、与えられている。さんがあなたのID IDC_FUNKY
を持っていると仮定しましょう。)
HINSTANCE hInstance = ::GetModuleHandle(NULL); // get a handle to the app's instance
HCURSOR hCursor = ::LoadCursor(hInstance, MAKEINTRESOURCE(IDC_FUNKY));
は今、あなたのEXEに埋め込まれたリソースからあなたのファンキーなカーソルをロードしました。もちろん、LoadCursor
を使用して、あらかじめ定義されたシステムカーソルをロードすることもできます。これを行うには、最初のパラメータにNULL
を渡します。これは、アプリケーションのリソースからロードするのではなく、システムからロードするためです。たとえば、のは、ヘルプカーソルをロードしてみましょう:
HCURSOR hCursorHelp = ::LoadCursor(NULL, IDC_HELP);
グレート-今、私たちは、カーソルをロードする方法を知っています。 1つのことを除くすべて:私たちが扱ったカスタムカーソルはすべてCUR(またはANI)ファイルとして保存されています。あなたはPNGファイルからカーソルをロードしたいという質問に言及します。正直なところ、私の提案はではなく、である。 PNGファイルをCURファイルに変換し、CURファイルを使用できるカーソル作成プログラムを使用します。それ以外の場合は、PNGファイルを読み込んでビットマップに変換し、そのビットマップをカーソルに変換する無意味なコードを書くことが忙しくなります。あなたが始めるとすぐにレンガの壁に当たるでしょう。 Win32 APIを使用してPNGイメージを読み込む明白な方法はありません。 GDI +、Windows Imaging Component、またはPNGファイルを処理できるサードパーティのライブラリを使用する必要があります。完全にこの答えの範囲外です。このウサギの穴を下りたい場合は、hereとhereを参照してください。それ以外の場合は、Greenfish Icon Editorのようなものをダウンロードして、変換を一度行い、あなたの人生に乗ってください。一緒にすべてを置く
は、それから、ここにあなたが何をすべきかです:
- は、あなたのPNGファイルは、ICOファイルに変換し、リソースとしてアプリケーションにこのICOファイルを追加します。これはVisual Studio内から簡単に実行できます。
LoadCursor
関数を呼び出して、リソースからカーソルをロードするコードを作成します。これはHCURSOR
です。初期化ルーチンで、アプリケーションを最初に起動するときにこれを行うのが賢明でしょう。返されたハンドルをキャッシュして、アプリケーションの存続期間全体にわたって使用できるようにします。コントロールがダイアログ上にある場合は、WM_INITDIALOG
でこれを行うことができます。
あなたのコントロールのためにWM_SETCURSOR
メッセージを処理してください。あなたがサブクラス化することでこれを行うことができますが、ほとんどの場合、それだけで親のウィンドウプロシージャにコードを配置するのが最も簡単です:
static HCURSOR hCursorFunky;
...
case WM_SETCURSOR:
{
// If we're the control that should get the cursor treatment...
if (static_cast<HWND>(wParam) == hwndYourControl)
{
::SetCursor(hCursorFunky);
return TRUE; // indicate we processed this message
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam); // do default handling
}
または、ダイアログ内のコントロールの生活、わずかな変化の場合:
case WM_SETCURSOR:
{
if (static_cast<HWND>(wParam) == ::GetDlgItem(hWnd, IDC_YOURCONTROL))
{
::SetCursor(hCursorFunky);
::SetWindowLongPtr(hWnd, DWLP_MSGRESULT, TRUE);
return TRUE; // indicate we processed this message
}
return FALSE; // do default handling
}
最後の注意:あなたが適切にどこのWindows SDKを見つけるために、リンカに語っていないことを示唆している、あなたの質問にリンカエラーを表示します。このビジネスはすべてVisual Studioの "Win32 Application"テンプレートによって自動的にセットアップされます。あなたはそれを使って新しいプロジェクトを作るべきです。もしそうでなければ、あなたのプロジェクトの設定に入り、リンカに(少なくとも)kernel32.lib
,user32.lib
、およびgdi32.lib
を使用するように指示する必要があります。そうしないと、リンカは呼び出しようとしているWindows API関数を見つけることができません。
カーソルがボタン上にある場合にのみカスタムカーソルが必要ですか?または、カーソルをフォーム全体のカスタムなものにする必要がありますか? – Rakete1111
@ Rakete1111。うん、そうだよ。正確には、ピクチャボックス。 (フォーム全体ではありません) –
[this](http://stackoverflow.com/questions/10277966/how-to-change-the-cursor-on-a-button) – Rakete1111