電子書籍の厳選無料作品が豊富!

■C言語とWIN32APIで下記の様にコーテイングしています。
■MessageBox(NULL,text,"条件",MB_YESNO);
[質問-1]
・[はい][いいえ]の2個のボタンが表示されるが、当初からカーソルが[はい]ボタンの上にある様に出来ませんか?

[質問-2]
表示位置や表示サイズなどを制御出来ませんか

ウインドウの場合、下記の関数など使用して対応しました
・GetWindowRect();
・SetCursorPos();
・GetCursorPos();
・SetForegroundWindow();
.........
.........

MessageBox()の場合はどうすれば良いですか?

A 回答 (3件)

初期ボタンはMB_DEFBUTTON1あたりのスタイルでできそうでは。


MSDN
http://msdn.microsoft.com/ja-jp/library/cc410914 …

サイズ等はフックするぐらいでしょうか?
あまりいじるのであればダイアログを自作したほうがベターかも。
参考
http://park15.wakwak.com/~opapa/cpp/Hook.htm

この回答への補足

ご教示ありがとうございます。
>初期ボタンはMB_DEFBUTTON1あたりのスタイルでできそうでは。
■私も一応ここを見たのですが・・・
・初期状態で有効なボタンを指定する事は出来るのですが
・マウスカーソルをそこに設定する方法が分かりません。

・ウィンドウ(hWnd,hButton,hCombo,hStatic....)ですと
GetWindowsRect();
SetCursorPos();
で何とか成ったのですが
MessageBox()の場合はどうすれば良いですか?

補足日時:2010/01/07 16:42
    • good
    • 0

 こんばんは。



 MessageBox()を呼び出す前にスレッドを回して、モーダルループを通り抜け、スレッドの中からMessageBox()のハンドルを掴めば良いのでは。
 MessageBox()のウィンドウクラス名が"#32770"なので、此れを利用してFindWindow()でハンドルを摘まみ出して、いじくれば目的は達成されます。
 強引ですが、以下参考程度に。

DWORD WINAPI ThreadProc(LPVOID p)
{
volatile HWND hWnd = static_cast<HWND>(p);
MSG msg;
while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == FALSE)
{
::Sleep(0);
HWND hMsgBox = ::FindWindow(TEXT("#32770"), NULL);
if(hWnd == ::GetParent(hMsgBox))
{
//MessageBoxを移動する
RECT rc;
::GetWindowRect(hMsgBox, &rc);
::MoveWindow(hMsgBox, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE);

//OKボタンの中央にマウスカーソルを持ってくる
HWND hButton = ::GetDlgItem(hMsgBox, IDOK);
::GetWindowRect(hButton, &rc);
::SetCursorPos(rc.left + ((rc.right - rc.left) / 2), rc.top + ((rc.bottom - rc.top) / 2));
::ExitThread(0);
}
}
return 0;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
::DestroyWindow(hwnd);
return 0;

case WM_NCDESTROY:
::PostQuitMessage(0);
return 0;
}

return ::DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pszArgs, int showCmd)
{
MSG msg;

WNDCLASSEX wc = {sizeof(wc)};
wc.lpszClassName = TEXT("TEST");
wc.lpfnWndProc = &::WndProc;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.hInstance = hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);

if(!::RegisterClassEx(&wc))
return 0;

HWND hWnd = ::CreateWindowEx(0, wc.lpszClassName, NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, 0);

::ShowWindow(hWnd, SW_SHOW);

DWORD dwTID;
HANDLE hThread = ::CreateThread(NULL, 0, &::ThreadProc, hWnd, 0, &dwTID);
::MessageBox(hWnd, TEXT("test"), TEXT("test"), IDOK);

//万が一MessageBoxを発見出来なかった時に備えて、WM_QUITをポストする
::PostThreadMessage(dwTID, WM_QUIT, 0, 0);
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);

while(::GetMessage(&msg, NULL, 0, 0) == TRUE)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}

return msg.wParam;
}
    • good
    • 0
この回答へのお礼

ありがとうございます。

サンプルプログラム有難う御座います
私がパットみて理解できないので、しばらく勉強させて下さい。

お礼日時:2010/01/09 08:49

やるとすれば MessageBoxの第一引数を表示するための(親)ウィンドウのハンドルを渡してやったほうがいいかもしれません


こうすれば 親ウィンドウの中心にMessageBoxが表示されると思います

後は MessageBox()を呼ぶ前に [はい]ボタンが来るであろう位置を計算しておいて SetCursorPosを先に実行してから MessageBox()を呼んでやるという具合になると思います

MessageBox自体が特殊なモーダルダイアログなので表示後に外部からの割り込み操作ができません

別の方法としては マウスドライバー側の設定で デフォルトボタンを追いかける機能を使うようにするとかでしょう
# ユーザーが設定を解除してしまった場合は無効になりますが ・・・

この回答への補足

ご教示すありがとうございます、
>MessageBox()を呼ぶ前に [はい]ボタンが来るであろう位置を計算しておいて SetCursorPosを先に実行してから MessageBox()を呼んでやるという具合になると思います

■上記の方法で出来ました、「関数をを呼ぶ前...」これもミソですね

■しかしMessageBox()のハンドル等はどこかで得られないものなのでしょうか、

>別の方法としては マウスドライバー側の設定で デフォルトボタンを追いかける機能を使うようにするとかでしょう
■もう少し、ヒントをください。

補足日時:2010/01/08 09:21
    • good
    • 0

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