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

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だとプロセスが終了しません。
文字セットをマルチバイトに変更するとプロセスは終了します。
なお、メイン関数を終了はしている様子。
どなたか理由がお分かりになる方はおられませんでしょうか?
お手数ですがご回答いただければ幸いです。

A 回答 (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後のメッセージがあるのか?
ないのか?という点については私も解らないのです。
もしご存知でしたら教えていただければ幸いです。

補足日時:2009/06/11 00:06
    • good
    • 0
この回答へのお礼

Yanch様、ご回答いただき誠にありがとうございます。
あれからご紹介していただいたURLのコードをコピペして
ビルドしたところUnicodeでも異常なく終了しました。
実際のところどこが違うか判断しかねるのですが、
このコードを参考にして、モジュール分解等していきたいと思います。
(基本的にC++でクラス化するつもりでいます。)
ご回答、誠にありがとうございました。

お礼日時:2009/06/11 12:14

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