Visual Studio 2008 のVC++ でのアプリ開発について困っています。
開発環境はOS:Vista Ultimate 64bitです。
開発しようとしているのはWin32プロジェクトです。
先ず以下がソースです。
---
/** @brief メインファイル */
// Option declarations
#define STRICT
#define WIN32_LEAN_AND_MEAN
// Includes
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<tchar.h>
#include<process.h>
#include<windows.h>
#include<windowsx.h>
#include<winerror.h>
// Constance declarations
#define WND_CX (1024)
#define WND_CY (768)
#define ERR_QUIT (-1)
// Structures declarations
typedef struct _winapp
{
HINSTANCE hInst;
HWND hWnd;
TCHAR sTitle[128];
TCHAR sWndClass[128];
}WINAPP, *PWINAPP;
// Prototype declarations
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
HRESULT Init(WINAPP& app);
long Uninit(WINAPP& app);
WPARAM MsgLoop(WINAPP& app);
long Idle(void);
// Global variables
WINAPP g_app;
/** @brief Entry point */
int WINAPI ::_tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR pCmdLine, int shwcmd)
{
// Win32App initialize
::memset(&g_app, 0, sizeof(g_app));
g_app.hInst = hInst;
::_tcscpy_s(g_app.sTitle, sizeof(g_app.sTitle), _T("myapp"));
::_tcscpy_s(g_app.sWndClass, sizeof(g_app.sWndClass), _T("myapp"));
HRESULT hr = ::Init(g_app);
if(FAILED(hr))
return ERR_QUIT;
// Message loop
WPARAM wp = ::MsgLoop(g_app);
// WinApp32 uninitialize
::Uninit(g_app);
return (int)wp;
}
/** @brief Main window procedure */
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch(msg){
case WM_DESTROY:
::PostQuitMessage(0);
g_app.hWnd = NULL;
break;
default:
return ::DefWindowProc(hWnd, msg, wp, lp);
}
return 0;
}
/** @brief Initialize win32 application */
HRESULT Init(WINAPP& app)
{
// Register window class
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)::WndProc;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = app.hInst;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = app.sWndClass;
if(::RegisterClassEx(&wc)==0)
return ::GetLastError();
// Create main window
RECT rc = { 0, 0, WND_CX, WND_CY};
::AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
g_app.hWnd = ::CreateWindow( app.sWndClass, app.sTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, app.hInst, NULL);
if(app.hWnd==NULL)
return ::GetLastError();
// Show window
::ShowWindow(app.hWnd, SW_SHOWNORMAL);
::UpdateWindow(app.hWnd);
return S_OK;
}
/** @brief Uninitalize win32 application */
long Uninit(WINAPP& app)
{
return ::UnregisterClass(app.sWndClass, app.hInst);
}
/** @brief Message loop */
WPARAM MsgLoop(WINAPP& app)
{
MSG msg = {};
while(msg.message!=WM_QUIT){
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}else{
// Idle process
if(Idle()==0)
::DestroyWindow(app.hWnd); // Occur error and exit application.
}
}
return msg.wParam;
}
/** @brief Idle process */
long Idle(void)
{
return 1;
}
---
以上がソースなのですがプロジェクトのプロパティの文字セットが
Unicodeだとプロセスが終了しません。
文字セットをマルチバイトに変更するとプロセスは終了します。
なお、メイン関数を終了はしている様子。
どなたか理由がお分かりになる方はおられませんでしょうか?
お手数ですがご回答いただければ幸いです。
No.1ベストアンサー
- 回答日時:
> while(msg.message!=WM_QUIT){
WM_QUITを処理した後、終了してるみたいですけど、ここが気になります。
WM_QUITの後には、処理すべきメッセージは来ないんですかね。
Win32 アプリケーションの作成 (C++)
http://msdn.microsoft.com/ja-jp/library/bb384843 …
この回答への補足
ご回答いただきありがとうございます。
私もメッセージループ関連だとは当ては付いているんです。
メッセージループ処理を省くとプロセスは終了しているようなのです。
ただ、メイン関数終了後までデバッグでステップを進めると逆アセンブルに入ってしまうので…
アセンブリ言語は残念ながらほとんど触ったことがないのです。
WM_QUITですがWin32アプリケーションの終了は
PostQuitMesssage(正常or異常値)でWM_QUITをメッセージキュー
に送ればいい、というように学んできたので、どうして?
というのが正直なところです。
PeekMessage()はWM_QUITを必ず取得するので無限ループにはならない。
PeekMessage関数
http://msdn.microsoft.com/ja-jp/library/cc410948 …
もしあるとすればWM_EXITというメッセージが考えられないこともないんですが、これはOSがアプリ起動時にシャットダウンするときなどに
送るものらしいと聞いたことがあるので可能性としては低いと思っています。
そもそもマルチバイト文字セットだとプロセス(アプリ)が終了しているのが解りません。Unicodeだとなぜだめなのか?
また、VC++6.0などのプロジェクトを2008にアップグレードし、
Unicode文字セットにしてもちゃんと終了しています。
ずっとMFCで、しかもマルチバイトでやってきたのでUnicodeで
べた書きは初めてしています。
もしかしたら環境依存の不具合かな、とも思っており
再インストールも検討中です。
情けないことにメッセージに関して精通していないので
Yanch様のおっしゃられるWM_QUIT後のメッセージがあるのか?
ないのか?という点については私も解らないのです。
もしご存知でしたら教えていただければ幸いです。
Yanch様、ご回答いただき誠にありがとうございます。
あれからご紹介していただいたURLのコードをコピペして
ビルドしたところUnicodeでも異常なく終了しました。
実際のところどこが違うか判断しかねるのですが、
このコードを参考にして、モジュール分解等していきたいと思います。
(基本的にC++でクラス化するつもりでいます。)
ご回答、誠にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- その他(プログラミング・Web制作) laravel 本番環境でメールが送れません。 1 2023/02/17 17:57
- その他(プログラミング・Web制作) python flask から fastapiへの移行時のエラー対処 1 2023/02/05 12:26
- その他(プログラミング・Web制作) Visual StudioでDjangoのプロジェクト配下のappを作成する方法 1 2022/05/01 03:47
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Win32APIにて、ウィンドウ全体...
-
音量調節
-
C++のcase文の書き方
-
Win32APIでウィンドウを中央に...
-
トラックのループの仕方
-
LoadImageとSetCursorについて
-
C言語のfor文です。 繰り返しの...
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
Enterキーを押されたら次の処理...
-
*をユーザーが入力した数字の数...
-
fgetsなどのときのstdinのバッ...
-
C言語で%を使わない余りの出し方
-
C言語
-
プログラムでの数字につく”f”の...
-
break文でループを一気に抜ける...
-
マイナスからプラスへ転じた時...
-
#define _CRT_SECURE_NO_WARNIN...
-
既定のコンストラクタがありま...
-
ある商品のロス率を5%見込み、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エディットボックスの背景の色...
-
ダイアログプログラムでEnterキ...
-
C言語win32api、エディットボッ...
-
音量調節
-
エディットコントロール入力時...
-
プログラミングでエラーが出ま...
-
エラー Run-Time Check Failur...
-
キャレットの現在位置の表示 (W...
-
LoadImageとSetCursorについて
-
コンソールアプリケーションの...
-
画像を表示したいのですが……
-
ボタンの色(WINAPI)
-
COMPORTマルチスレッドで例外発生
-
C++のcase文の書き方
-
Win32APIでウィンドウを中央に...
-
PeekMessageについて
-
CTreeCtrlのCreate関数でエラー...
-
オーバーレイみたいな処理がしたい
-
この列挙体でsysjanの関数はあ...
-
DirectInputについて再
おすすめ情報