• ベストアンサー

WM_QUERYENDSESSIONを使って次文で

#include <windows.h> LRESULT CALLBACK WndProc(HWND hW,UINT ms,WPARAM wp,LPARAM lp) { HDC hD; PAINTSTRUCT ps; static int width=0,height=0; static TCHAR strSize[128]; static boolean b_logoff; int i; switch(ms) { case WM_QUERYENDSESSION: b_logoff=true; i=MessageBox(hW,"end?","?",MB_YESNO|MB_TOPMOST); if(i==IDNO)b_logoff=false; case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return b_logoff; case WM_SIZE: width=LOWORD(lp); height=HIWORD(lp); return b_logoff; case WM_PAINT: hD=BeginPaint(hW,&ps); wsprintf(strSize,"width = %d : height= %d",width,height); TextOut(hD,10,10,strSize,lstrlen(strSize)); EndPaint(hW,&ps); return b_logoff; } return DefWindowProc(hW,ms,wp,lp); } ユーザがWindowsを終了させようとしたときに ウォーンング用の警告ボックスを表示したのですが Noボタンを押してもWindowsが終了してしまいます 何が悪いのでしょうか?

  • keyguy
  • お礼率68% (895/1314)

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

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

>case WM_QUERYENDSESSION: >のときも >case WM_CLOSE: >case WM_DESTROY: >の後の処理を行わせる事にしているのです なんで? PostQuitMessage(0); 呼び出すから終わっちゃうんですけど。 そもそもWM_CLOSEでPostQuitMessage()呼ぶのもおかしいんですけど。

keyguy
質問者

お礼

ありがとうございます PostQuitMessage(0); を使ったのはこれを使ってもメインウィンドウが壊されるとは限らないと書いていたからです 試行錯誤で何とかやってみます

その他の回答 (3)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.4

>WM_QUERYENDSESSIONもWM_CLOSEもWM_DESTROYもWM_PAINTもみんな戻り値がおかしい。 この上の文章、なんか少し誤解されてるかも。 WM_PAINTもWM_CLOSEもWM_DESTROYもおかしいというのは、すべて常に0を返さないといけないからということです。 変数を使ってる時点で変です。 という意味で書いてます。LRESULTじゃないからということでは無いです。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

WM_QUERYENDSESSIONもWM_CLOSEもWM_DESTROYもWM_PAINTもみんな戻り値がおかしい。 WM_QUERYENDSESSIONに対する処理は#1の方のとおりに構造がおかしい。 そもそもFALSEとfalseは別物だしウィンドウプロシージャの戻り値はLRESULT。boolじゃないし。 で、一番の原因はWM_QUERYENDSESSION中のメッセージボックスで「いいえ」を押されたときにプロシージャの戻り値でFALSEを返してないこと。 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/wm_queryendsession.asp

keyguy
質問者

お礼

falseをFALSEにtrueをTRUEにかえてやってみましたが結果は同じでした 何かいい方法は無いでしょうか?

keyguy
質問者

補足

ありがとうございます No.1の補足に 1行抜けていたので追加しておきました これでも論理的におかしいのでしょうか?

回答No.1

if(i==IDNO)b_logoff=false; の後、break も return もありませんけど、それでいいのですか?

keyguy
質問者

お礼

ありがとうございます case WM_QUERYENDSESSION: のときも case WM_CLOSE: case WM_DESTROY: の後の処理を行わせる事にしているのです 一行抜けていました あわせてWinMainも付けてみます LRESULT CALLBACK WndProc(HWND hW,UINT ms,WPARAM wp,LPARAM lp) { HDC hD; PAINTSTRUCT ps; static int width=0,height=0; static TCHAR strSize[128]; static boolean b_logoff; int i; b_logoff=false; switch(ms) { case WM_QUERYENDSESSION: b_logoff=true; i=MessageBox(hW,"end?","?",MB_YESNO|MB_TOPMOST); if(i==IDNO)b_logoff=false; case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return b_logoff; case WM_SIZE: width=LOWORD(lp); height=HIWORD(lp); return b_logoff; case WM_PAINT: hD=BeginPaint(hW,&ps); wsprintf(strSize,"width = %d : height= %d",width,height); TextOut(hD,10,10,strSize,lstrlen(strSize)); EndPaint(hW,&ps); return b_logoff; } return DefWindowProc(hW,ms,wp,lp); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,PSTR,int) { HWND hW; MSG ms; WNDCLASS winc; winc.style=CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc=WndProc; winc.cbClsExtra=winc.cbWndExtra=0; winc.hInstance=hInstance; winc.hIcon=LoadIcon(NULL,IDI_APPLICATION); winc.hCursor=LoadCursor(NULL,IDC_ARROW); winc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName=NULL; winc.lpszClassName=TEXT("KITTY"); if(!RegisterClass(&winc))return -1; hW=CreateWindow ( TEXT("KITTY"),TEXT("end test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL ); if(hW==NULL)return -1; while(GetMessage(&ms,NULL,0,0))DispatchMessage(&ms); return ms.wParam; }

keyguy
質問者

補足

#include <windows.h> LRESULT CALLBACK WndProc(HWND hW,UINT ms,WPARAM wp,LPARAM lp) { HDC hD; PAINTSTRUCT ps; static int width=0,height=0; static TCHAR strSize[128]; static int logoff; int i; logoff=0; switch(ms) { case WM_QUERYENDSESSION: logoff=1;; i=MessageBox(hW,"end?","?",MB_YESNO|MB_TOPMOST); if(i==IDNO)logoff=0; case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return logoff; case WM_SIZE: width=LOWORD(lp); height=HIWORD(lp); return logoff; case WM_PAINT: hD=BeginPaint(hW,&ps); wsprintf(strSize,"width = %d : height= %d",width,height); TextOut(hD,10,10,strSize,lstrlen(strSize)); EndPaint(hW,&ps); return logoff; } return DefWindowProc(hW,ms,wp,lp); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,PSTR,int) { HWND hW; MSG ms; WNDCLASS winc; winc.style=CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc=WndProc; winc.cbClsExtra=winc.cbWndExtra=0; winc.hInstance=hInstance; winc.hIcon=LoadIcon(NULL,IDI_APPLICATION); winc.hCursor=LoadCursor(NULL,IDC_ARROW); winc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName=NULL; winc.lpszClassName=TEXT("KITTY"); if(!RegisterClass(&winc))return -1; hW=CreateWindow ( TEXT("KITTY"),TEXT("end test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL ); if(hW==NULL)return -1; while(GetMessage(&ms,NULL,0,0))DispatchMessage(&ms); return ms.wParam; }

関連するQ&A

  • WM_PAINT

    WM_PAINT について教えてほしいのですが、 WM_PAINTがシステムから発行されるタイミングとして、 クライアント領域に無効領域がある時 UpdateWindow()を呼び出した時 InvalidateRect()を呼び出した時があると思いますが 例えば LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM) { LPCTSTR  Str = TEXT("Kitty"); switch (msg) { case WM_CREATE:    hdc = GetDC(hwnd);    SetTextColor(hdc , RGB(255, 0 , 0));    ReleaseDC(hwnd , hdc);    return 0; case WM_PAINT:    hdc = BeginPaint(hwnd , &ps);    TextOut(hdc, 10 , 10 , Str, lstrlen(Str));    EndPaint(hwnd , &ps);    return 0; } return DefWindowProc(hwnd , msg , wp , lp); } の場合, WM_PAINTはどのタイミングでシステムから呼び出されるんですか? WinMain()でUpdateWindow()もInvalidateRect()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。

  • Windowをドラッグ移動したい

    ために以下のようなコードを打ちましたが 素早く動かすとマウスがクライアント領域からはずれ タイトルバーをドラッグ移動したときのようになりません なにか方法はないでしょうか? case WM_MOUSEMOVE:  if(wP==MK_LBUTTON)  {   if(0<=i_x && 0<=i_y)   {    GetWindowRect(hW,&rt);    MoveWindow (hW, rt.left+LOWORD(lP)-i_x, rt.top+HIWORD(lP)-i_y, rt.right-rt.left,rt.bottom-rt.top,1);   }  }  else i_x=i_y=-1;  return 0; case WM_LBUTTONUP:  if(egg)i_x=i_y=-1;  return 0; case WM_LBUTTONDOWN:  i_x=LOWORD(lP);i_y=HIWORD(lP);  return 0;

  • 最初ボタンが見えない

    ボタンを大きく中央に表示するプログラムを作りました。 しかし中央をクリックするまでボタンが現れません。 どうしたら最初からボタンが現れるのでしょうか? またフォントをクリエイトし続けてリソースは尽きないのでしょうか? #include <windows.h> #include <stdio.h> HWND hB; LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP) { RECT rt; char s[99]; int W,H; static HFONT hF; switch(wM) { case WM_PAINT: GetClientRect(hW,&rt); W=rt.right-rt.left;H=rt.bottom-rt.top; DeleteObject(hF); hF=CreateFont(H/4,W/4,0,0,FW_NORMAL,FALSE,FALSE,FALSE,SHIFTJIS_CHARSET,OUT_TT_ONLY_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH|FF_MODERN,"MS Pゴシック"); SendMessage(hB,WM_SETFONT,(WPARAM)hF,1); MoveWindow(hB,W/4,H/4,W/2,H/2,1); sprintf(s,"幅=%d,高さ=%d",H,W);SetWindowText(hW,s); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return(DefWindowProc(hW,wM,wP,lP)); } } WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { WNDCLASS wc; --略--(ここにウィンドウクラスwcをクラス名"I"で登録) RegisterClass(&wc); hW=CreateWindow("I","ボタンの親",WS_OVERLAPPEDWINDOW,0,0,0,0,0,0,hI,0); hB=CreateWindow("BUTTON","子",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,0,0,0,0,hW,0,hI,0); ShowWindow(hW,SW_SHOWMAXIMIZED); UpdateWindow(hW); while(GetMessage(&ms,0,0,0)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); }

  • プログラムを終わらせてください。

    下のプログラムが終わらなくて困っています。 終わらせる方法を教えてください。 #include <windows.h> #pragma argsused HWND hWmain; DWORD WINAPI Th(LPVOID) { char s[99]; for(unsigned i=0;i<4294967295;i++) SetWindowText(hWmain,itoa(i++,s,10)); return 0; } LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP) { static HANDLE hTh; DWORD thId; DWORD ExitCode; switch(wM) { case WM_CREATE: hTh=CreateThread(0,0,Th,0,0,&thId); return 0; case WM_DESTROY: GetExitCodeThread(hTh,&ExitCode); ExitThread(ExitCode); if(hTh!=0)CloseHandle(hTh); PostQuitMessage(0); return 0; default: return(DefWindowProc(hW,wM,wP,lP)); } } WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { WNDCLASS wc; MSG ms; wc.lpszClassName ="Q"; wc.lpfnWndProc =(WNDPROC)WinProcedure; wc.hInstance =hI; wc.style =CS_HREDRAW|CS_VREDRAW; wc.cbClsExtra =0; wc.cbWndExtra =0; wc.hIcon =LoadIcon(hI,0); wc.hCursor =LoadCursor(0,IDC_ARROW); wc.hbrBackground =(HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName =0; RegisterClass(&wc); hWmain=CreateWindow("Q","",WS_OVERLAPPEDWINDOW,0,0,99,99,0,0,hI,0); ShowWindow(hWmain,SW_SHOW); UpdateWindow(hWmain); while(GetMessage(&ms,0,0,0)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); }

  • WM_KEYDOWNでPrtScを捕まえる方法??

    ごく普通のウィンドウプロシージャでキーの判別を行っています 下記のように条件(1)が WM_KEYUP の際には(2)、(3)ともに検出します LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_KEYUP: ............ (1) switch(wp) { case VK_RETURN: { break; } ..... (2) case VK_SNAPSHOT: { break; } ..... (3) default: { break; } } break; } return; ところが条件(1)を WM_KEYDOWN に変更すると(2)の Enter は検出しますが、(3)の PrtSc を検出してくれません 質問1 なぜ PrtSc を WM_KEYDOWN では検出しないのですか? 質問2 WM_KEYUP WM_KEYDOWN のいずれか一方にしか反応しないキーはまだありますか? 質問3 どのようにしたら PrtSc の WM_KEYDOWN を捕まえることが出来ますか? 自分でも調べてみましたが、どうも判然と致しません 宜しくご指導のほどお願い申し上げます

  • WM_INITDIALOGのフック

    どこにも載っていないため質問させていただきます。 次のようなコードを書いたとき、ダイアログの出現の検知ができるWM_INITDIALOGを検知できないのはなぜでしょうか。 hHookForDialog = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProcForDialog, hDll, 0); LRESULT CALLBACK CallWndRetProcForDialog(int nCode, WPARAM wp, LPARAM lp) { if(nCode < 0) return CallNextHookEx(hHookForDialog, nCode, wp, lp); PCWPRETSTRUCT Wmes = (PCWPRETSTRUCT)lp; if(nCode == HC_ACTION) { if(Wmes->message == WM_INITDIALOG) { PostMessage(hWndToSendMessage, mesDialogCreated, (WPARAM)(Wmes->hwnd), NULL); } } return CallNextHookEx(hHookForDialog, nCode, wp, lp); } フック自体は成功しているようで、条件文を外すとメッセージはたくさん飛んできます。 けれども目的のWM_INITDIALOGは無いようです。 どうすればいいのかご教授お願いします。

  • void main(void){...}だとDosWindowが開くので

    わざわざWindowsアプリにして以下のようにするしかないのでしょうか? LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP) { //ここに宣言を置く switch(wM) { case WM_CREATE: //ここに処理を置く return 0; default: return(DefWindowProc(hW,wM,wP,lP)); } } WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS) { WNDCLASS wc; HWND hW,hPW; MSG ms; wc.lpszClassName ="goo"; wc.lpfnWndProc =(WNDPROC)WinProcedure; wc.hInstance =hI; wc.style =CS_HREDRAW|CS_VREDRAW; wc.cbClsExtra =NULL; wc.cbWndExtra =NULL; wc.hIcon =LoadIcon(NULL,IDI_EXCLAMATION); wc.hCursor =LoadCursor(NULL,IDC_ARROW); wc.hbrBackground =(HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName =NULL; RegisterClass(&wc); hW=CreateWindow ( "goo", "教えて!goo", WS_OVERLAPPED, 0, 0, 640, 456, NULL, NULL, hI, NULL ); ShowWindow(hW,nCS); UpdateWindow(hW); while(GetMessage(&ms,NULL,NULL,NULL)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); } もっと簡単にDosWindowが開かないようにする方法はないのでしょうか? もしないとすると上記記述でもっと簡単にできないでしょうか?

  • LPTSTR型の変数に文字を格納

    LPTSTR型の変数に文字を格納 現在C言語でWindowsプログラミングを学習しています。 LPTSTR 型の変数にキーボードから入力されて1文字づつ格納したいのですが、 下記のコードであればうまくいきません。 自分がTCHARやLPTSTRのことを根本から理解できていないのが原因だと思うのですが。 LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { static LPTSTR buffer; HDC hdc; PAINTSTRUCT ps; switch(msg){ case WM_CHRAR: *buffer++=(TCHAR)wp; InvalidateRect(hWnd,NULL,TRUE); return 0; case WM_PRINT: hdc=BeginPaint(hWnd,&ps); DrawText(hdc,buffer,-1,&rc,DT_WORDBREAK); EndPaint(hWnd,&ps); return 0; ・ ・ ・ ・

  • WindowsSDKのCALLBACK内について

    猫でも分かるWindowsSDKを参考にして、とりあえずウィンドウプロシージャの関数内を下のようにしてプログラムを組んでみました。 //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_CREATE: break; case WM_TIMER: break; case WM_PAINT: break; case WM_COMMAND: break; case WM_CLOSE: SendMessage(hWnd, WM_DESTROY, wp, lp); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; } しかし、これで何もないWindow表示をさせるとCPU使用率が80%くらいまで跳ね上がります。 調べてみたところcase WM_PAINT:を削ったらCPU使用率が下がりました。 普通にクライアント領域に文字を表示したり画像を表示したりするだけだったら、それほどCPU使用率が上がらないのに、上のようにあらかじめ用意しておいたらCPU使用率が跳ね上がるのは何故でしょうか。 まだ勉強したてでレベルの低い質問でしたらすみません。

  • DeleteObjectについて(初心者です)

    今こちらのサイトを参考に、APIを学んでいるものです。 http://wisdom.sakura.ne.jp/system/winapi/win32/win26.html 質問させて頂きますのはここの部分です。 LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { HDC hdc; static LOGPEN lopnPen; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_CREATE: lopnPen.lopnStyle = PS_SOLID; lopnPen.lopnWidth.x = 5; lopnPen.lopnColor = 0XFF; return 0; case WM_PAINT: hdc = BeginPaint(hwnd , &ps); SelectObject(hdc , CreatePenIndirect(&lopnPen)); Ellipse(hdc , 10 , 10 , 200 , 50); DeleteObject(SelectObject(hdc , GetStockObject(WHITE_BRUSH))); EndPaint(hwnd , &ps); return 0; } return DefWindowProc(hwnd , msg , wp , lp); } 一度yahoo知恵袋にて質問したのですが、別の面で少し疑問が残ったのでここでもう一度質問させて頂きます。 SelectObjectは引数で渡されたオブジェクトを選択中にし、返り値として以前に選択していたオブジェクトを返すという回答がありましたが、それならば DeleteObject(SelectObject(hdc , GetStockObject(WHITE_BRUSH))); のGetStockObjectの引数WHITE_BRUSHを別のもの(例えばBLACK_PEN)に置き換えても、返り値は以前選択していたオブジェクトのままなので何も相違ないはずですよね? 当方理解もままならない初心者ですから盛大な勘違いをしているかもしれません。 分かる方、どうかご教授お願いします。

専門家に質問してみよう