• ベストアンサー

1つだけしか起動しないアプリを作りたい

下のようにして1つだけしか起動しないアプリを以前(Borland C++4.0で)作っていてうまく動いていたのですが 無償Borland C++5.5ではうまくいきません 調べてみるとhPIが2つ目以降のクローンについても0なのです hPIが使えないとすると他にどんな方法があるのでしょうか? WINAPI WinMain(HINSTANCE hI,HINSTANCE hPI,LPSTR lpszCP,int nCS) { WNDCLASS wc; HWND hW; MSG ms; if(hPI!=NULL)return(0);

  • nubou
  • お礼率62% (293/470)

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

  • ベストアンサー
noname#4252
noname#4252
回答No.2

ミューテックスを使用するならば OpenMutex()しないで、CreateMutex()の戻り値とGetLastError()で判断するべき。

参考URL:
http://techtips.belution.com/ja/vc/0025/
nubou
質問者

お礼

まんまのリンクありがとうございました ミューテックスを使うのが常道になっているのですね

その他の回答 (1)

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

Windows95 から WinMain の hPrevInstance は常に NULL です。 こういう場合には、Mutex を使います。 きっと、こういう感じ。 OpenMutex(~ アプリをあらわす一意な文字列); if (オープンできたら) {   /* 別のアプリがあるはずなので */   多分、OpenMutex の後始末をして   return 0; } else {   CreateMutex(~ アプリをあらわす一意な文字列); } メッセージループ ReleaseMutex() # 細かいところは調べてね

nubou
質問者

お礼

早い回答ありがとうございました

関連するQ&A

  • lpszCPを取り出したい

    Winアプリにファイルをドラッグしてファイル名を取るために下記のような記述をして一応取り出せたのですが str_argにような外部変数を利用するよりも正当なやり方はないのですか? 例えばメッセージのメンバに格納されている場合にはそれを使うとか・・・ よろしくお願いします string str_arg; LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP); WINAPI WinMain(HINSTANCE hI,HINSTANCE hPI,LPSTR lpszCP,int nCS) { WNDCLASS wc; HWND hW; MSG ms; str_arg=lpszCP;

  • 2重起動を防ぐために

    WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { WNDCLASS wc; HWND hW; MSG ms; HANDLE hMutex; hMutex=CreateMutex(NULL,TRUE,"UniqueName"); if(!hMutex)return FALSE; if (GetLastError()==ERROR_ALREADY_EXISTS)return FALSE; とすればよいいうサイトがあります。 こうした後、最終的にこのアプリを終了するときMutexを閉じる必要はあるのでしょうか。 アプリの終了で自動的に閉じられるから何もしなくてよいのでしょうか教えてください。

  • 再起動時、前起動分のハンドルを得る方法は?

    WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS) { WNDCLASS wc; HWND hW; MSG ms; //ここで前起動クローンのアプリやWindowのハンドルを取得したい 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|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU, 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); } 上記アプリで//行で前起動時のWindowのハンドルを得るにはどうしたらいいのでしょうか?

  • 再起動したとき前起動分を強制終了するには?

    WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS) { WNDCLASS wc; HWND hW; 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|WS_CAPTION|WS_THICKFRAME |WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU, 0, 0, 640, 480, NULL, NULL, hI, NULL ); ShowWindow(hW,nCS); UpdateWindow(hW); while(GetMessage(&ms,NULL,NULL,NULL)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); } のプログラムが2回目に起動したとき1回目の起動を強制終了するにはどうしたらいいのでしょうか?

  • 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が開かないようにする方法はないのでしょうか? もしないとすると上記記述でもっと簡単にできないでしょうか?

  • 次のWindowsアプリで

    メッセージボックスは他のアプリのWindowの下に隠れることはないのですが他のアプリのウィンドウをクリックするとメッセージボックスの焦点がぼけアクティブでなくなります メッセージボックスを常にアクティブにする方法を終えてください #include <windows.h> using namespace std; WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { HWND hW; hW=CreateWindow("STATIC","",WS_OVERLAPPED, 0,0,9,9,NULL,NULL,hI,NULL); SetWindowPos(hW,HWND_TOPMOST,0,0,9,9,NULL); MessageBox(hW,"OK?","",MB_OK); return 0; }

  • 2重軌道防止のサイトの説明

    に従って以下のようにしましたが 2重起動を発見してやめるために return false; としていますが return true; としたり booleanをやめて return int(0) とするとどうなるのでしょうか? WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { WNDCLASS wc; HWND hW,hPW; MSG ms; unsigned pos; HANDLE hMutex; hPW=FindWindow("goo","I am good."); hMutex=CreateMutex(NULL,TRUE,"UniqueName"); if(!hMutex)return FALSE; if (GetLastError()==ERROR_ALREADY_EXISTS) { ShowWindow(hPW,SW_RESTORE); SetForegroundWindow(hPW); return FALSE; } ・・・・・・・・・・・・・・・・・・・・

  • ブレイクポイントについて

    #include <windows.h> LRESULT CALLBACK WndProc( HWND , UINT, WPARAM, LPARAM ); LRESULT CALLBACK WndProc1( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR , int nCmdShow ) { MSG msg; HWND hWnd, hWnd3; WNDCLASSEX wndclass,c_wndclass; wndclass.style = 0; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wndclass.hIconSm = LoadIcon( NULL, IDI_WINLOGO ); wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "wh02"; c_wndclass.style = 0; c_wndclass.lpfnWndProc = WndProc1; c_wndclass.cbClsExtra = 0; c_wndclass.cbWndExtra = 0; c_wndclass.cbSize = sizeof(WNDCLASSEX); c_wndclass.hInstance = hInstance; c_wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); c_wndclass.hIconSm = LoadIcon( NULL, IDI_WINLOGO ); c_wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); c_wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); c_wndclass.lpszMenuName = NULL; c_wndclass.lpszClassName = "wh01"; if(! RegisterClassEx( &wndclass )) return 0; // ウィンドウクラスの登録 if(! RegisterClassEx( &c_wndclass )) return 0; // ウィンドウクラスの登録 // できないと終了   hWnd = CreateWindow( "wh02", "親ウインドウ(WS_OVERLAPPEDWINDOW)", WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, // 親ウィンドウはデスクトップ NULL, hInstance, NULL ); hWnd2 = CreateWindow( "hWnd1", "親ウインドウの子", WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, // 親ウィンドウの子 NULL, hInstance, NULL ); ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); ShowWindow( hWnd2, nCmdShow ); UpdateWindow( hWnd2 ); while( GetMessage( &msg, NULL, 0, 0 ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); } return msg.wParam ; } LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ) { default: ブレイクポイント3return DefWindowProc( hWnd, iMessage, wParam, lParam ); } return 0; } LRESULT CALLBACK WndProc1( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ) { case WM_DESTROY: ブレイクポイント1postQuitMessage(0); break; ブレイクポイント2return DefWindowProc( hWnd, iMessage, wParam, lParam ); } のプログラムを組んで実行して、ブレークポイントでやったのですがまず親ウィンドウの終了ボタンを押したらブレイクポイント1が通り、次にブレイクポイント2が通りここまではいいのですがブレイクポイント3が三回繰り返して実行されるのですが、なぜ三回繰り返されるのでしょうか?

  • WinAPIでの画像高速切り替え表示プログラム2

    1の続きです。これを先に見た方は1から見てください。 お願いします。 int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) { WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = __FILE__; if(!RegisterClass(&wc)) return 0; HWND hWnd=CreateWindow( __FILE__," ", WS_POPUP | WS_VISIBLE, 0,0, 1024,768, NULL,NULL,hInstance,NULL); if(hWnd==NULL) return 0; // タイマを作成する SetTimer( hWnd, TIMER_ID, TIMER_ELAPSE, NULL ); BOOL bRet; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1) break; DispatchMessage(&msg); } // タイマを破棄する KillTimer( hWnd, TIMER_ID ); return (int)msg.wParam; } 2つに分かれてしまって申し訳ありません。 よろしくお願いします。

  • デフォルトウィンドウプロシージャ

    ある箇所が間違っていたので修正しました。ある本に子ウィンドウでデフォルトウィンドウプロシージャに渡すとそのメッセージは親ウィンドウすなわちトップレベルウィンドウへと渡されると載っていたので、試しにプログラムでやったのですが、 #include <windows.h> LRESULT CALLBACK WndProc( HWND , UINT, WPARAM, LPARAM ); LRESULT CALLBACK WndProc1( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR , int nCmdShow ) { MSG msg; HWND hWnd, hWnd3; WNDCLASSEX wndclass,c_wndclass; wndclass.style = 0; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wndclass.hIconSm = LoadIcon( NULL, IDI_WINLOGO ); wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "wh02"; c_wndclass.style = 0; c_wndclass.lpfnWndProc = WndProc1; c_wndclass.cbClsExtra = 0; c_wndclass.cbWndExtra = 0; c_wndclass.cbSize = sizeof(WNDCLASSEX); c_wndclass.hInstance = hInstance; c_wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); c_wndclass.hIconSm = LoadIcon( NULL, IDI_WINLOGO ); c_wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); c_wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); c_wndclass.lpszMenuName = NULL; c_wndclass.lpszClassName = "wh01"; if(! RegisterClassEx( &wndclass )) return 0; // ウィンドウクラスの登録 if(! RegisterClassEx( &c_wndclass )) return 0; // ウィンドウクラスの登録 // できないと終了   hWnd = CreateWindow( "wh02", "親ウインドウ(WS_OVERLAPPEDWINDOW)", WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, // 親ウィンドウはデスクトップ NULL, hInstance, NULL ); hWnd3 = CreateWindow( "hWnd1", "親ウインドウの子", WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, // 親ウィンドウの子 NULL, hInstance, NULL ); ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); ShowWindow( hWnd3, nCmdShow ); UpdateWindow( hWnd3 ); while( GetMessage( &msg, NULL, 0, 0 ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); } return msg.wParam ; } LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ) { HDC hdc; PAINTSTRUCT ps; char *p; int id; switch( iMessage ){ case WM_KEYDOWN: id = MessageBox(hWnd, (LPCSTR)"終了しますか", (LPCSTR)"終了確認", MB_OKCANCEL | MB_ICONQUESTION); if(id == IDOK) DestroyWindow(hWnd); case WM_DESTROY: PostQuitMessage(0); // メッセージループを終了させる break; default: return DefWindowProc( hWnd, iMessage, wParam, lParam ); } return 0; } LRESULT CALLBACK WndProc1( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ) { return DefWindowProc( hWnd, iMessage, wParam, lParam ); } とやったのですが子ウィンドウでキー入力しても終了しません。 なぜなのでしょうか?何か間違っているのでしょうか?

専門家に質問してみよう