• ベストアンサー

ウインドウ終了の取得ができません

以下にソースを #include <windows.h> #include <stdio.h> static int array[300] = {0}; static int temp[300] = {0}; static int count = 0; static int i = 0; BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lp) { static bool is_first = true; DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); if ( ::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && (style&WS_CAPTION) && !(style&WS_POPUP) ) { char buf[65536]; ::GetWindowText(hwnd, buf, 65535); if ( buf[0] != '\0' ){ if ( is_first ){ is_first = false; } else{ // 配列arrayにハンドルを代入 array[i] = int(hwnd) ; //printf("%d\n",i); i++; // 配列arrayに格納されたハンドル数 count++; } } } return TRUE; } int main(int argc, char** argv) { int a; int j = 0; int k = 0; int t_handend = 0; int flg = 0; char buf[65536]; // 無限ループ while(1){ // 起動しているアプリケーションのハンドル取得(配列arrayに格納) ::EnumWindows(EnumWindowProc, 0); i = 0; // temp内のハンドル数の計算 while(temp[t_handend] != 0){ t_handend++; } for(a=0;a<count;a++){ ::GetWindowText((HWND)array[a], buf, 65535); printf("array[%d]=%d=%s\n",a,array[a],buf); } for(a=0;a<t_handend;a++){ ::GetWindowText((HWND)temp[a], buf, 65535); printf("temp[%d]=%d=%s\n",a,temp[a],buf); } //printf("flg;%d\n",flg); for(k = 0; k < count; k++){ for(j = 0; j < t_handend; j++){ if(array[k] == temp[j]){ flg = 1; break; } } //printf("flg;%d\n",flg); if(flg != 1){ //printf("%d\n", array[i]); //プロセス名取得 ::GetWindowText((HWND)array[k], buf, 65535); printf("%sが起動しました\n", buf); //flg1=1; } flg = 0; } for(k = 0; k < t_handend ; k++){ for(j = 0; j < count; j++){ if(temp[k] == array[j]){ flg = 1; break; } } if(flg != 1){ ::GetWindowText((HWND)temp[k], buf, 65535); if((HWND)temp[k]!=0){ printf("%sが終了しました\n", buf); } //printf("%d\n", temp[i]); } flg = 0; } // tempの更新 for(j = 0; j < count; j++){ temp[j] = array[j]; } for(; j < 300; j++){ temp[j] = 0; } flg = 0; count = 0; puts(""); Sleep(3000); } return 0; } これでウインドが立ち上がったときと終了のログをとろうとしましたが、このままですと終了したウインドの名前がとれません。 どうしたらよいでしょうか。?

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス ・プログラムの起動と終了の監視について。  (1)ウインドウハンドルとそのキャプションを持つ構造体を用意。  (2)前回列挙した情報と今回列挙する情報を配列などに保存。  (3)1回の列挙で取得したウインドウハンドルを元にソート。  (4)前回、今回の列挙の差分から『起動』『終了』を判定。  (5)今回の列挙データを前回の列挙データとする。   なお、前回の列挙データ配列を次の列挙データ配列とする。   要するに列挙データの配列を入れ替えます。→ポインタなどで。  上記のような感じでプログラム(プロセス)の起動と終了の差分が取れます。 ・下に構造体の一例を載せます。 // 列挙管理に使用する最大データ数 #define MAX_ENUMPROCESS (100) // プロセス列挙の構造体を宣言 typedef struct enum_process_t {  HWND hWnd;  LPTSTR lpCaption; } stENUMPROC, *lpENUMPROC; // 起動・終了管理の構造体を宣言 typedef struct startup_log_t {  stENUMPROC stData1[ MAX_ENUMPROCESS ];  stENUMPROC stData2[ MAX_ENUMPROCESS ];  lpENUMPROC lpPrevious;  lpENUMPROC lpCurrent;  lpENUMPROC lpAppend;  DWORD   dwCount; } stSTARTUPLOG, *lpSTARTUPLOG; その他: ・lpPrevious が前回の列挙データ配列の先頭を表すポインタ。  lpCurrent が今回の列挙データ配列の先頭を表すポインタ。  lpAppend、dwCount は列挙時に使う変数。 ・上記の構造体を定義して列挙データを管理すると起動と終了の差分を見つけやすいです。  下に上記で構造体を使った起動と終了の差分を取る main() 関数を載せておきます。  インデント部は全角空白文字にしています。注意。  あと上手くソースを融合して下さい。 サンプル: #include <stdio.h> #include <stdlib.h> #include <windows.h> /* ここに構造体を定義 */ // 関数のプロトタイプ宣言 BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam ); VOID EnumStartupEmpty( lpSTARTUPLOG lpLog ); VOID EnumStartupList( lpSTARTUPLOG lpLog ); VOID EnumStartupNext( lpSTARTUPLOG lpLog ); VOID EnumStartupFirst( lpSTARTUPLOG lpLog ); // メイン関数 int main( void ) {  stSTARTUPLOG Log;    for ( EnumStartupFirst(&Log) ; ; EnumStartupNext(&Log) ){   lpENUMPROC lpA = Log.lpCurrent;   lpENUMPROC lpB = Log.lpPrevious;   DWORD dwCount = 0;      // 差分検査   system( "CLS" );   while ( (lpA->hWnd != NULL) && (lpB->hWnd != NULL) ){    if ( lpA->hWnd == lpB->hWnd ){     printf( "%3d:", ++dwCount );     printf( "[--]%p [%s]\n", lpA->hWnd, lpA->lpCaption );     lpA++;     lpB++;     continue;    }    if ( lpA->hWnd < lpB->hWnd ){     printf( "%3d:", ++dwCount );     printf( "[起動]%p [%s]\n", lpA->hWnd, lpA->lpCaption );     lpA++;    }    else{     printf( "%3d:", ++dwCount );     printf( "[終了]%p [%s]\n", lpB->hWnd, lpB->lpCaption );     lpB++;    }   }   // 起動   while ( lpA->hWnd != NULL ){    printf( "%3d:", ++dwCount );    printf( "[起動]%p [%s]\n", lpA->hWnd, lpA->lpCaption );    lpA++;   }   // 終了   while ( lpB->hWnd != NULL ){    printf( "%3d:", ++dwCount );    printf( "[終了]%p [%s]\n", lpB->hWnd, lpB->lpCaption );    lpB++;   }   printf( "dwCount = %d 個\n", Log.dwCount );   printf( "\n" );   Sleep( 1000 );  }  return 0; } 続く。

その他の回答 (2)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

続き。 // オーナー・ウインドウの判別 #define IsWindowOwner(h) (GetWindow(h,GW_OWNER) == NULL) // トップレベルのプロセスを列挙 BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam ) {  lpSTARTUPLOG lpLog = (lpSTARTUPLOG)lParam;  DWORD dwTextLen;  LPTSTR lpCaption;    if ( IsWindowVisible(hWnd) && IsWindowOwner(hWnd) ){   if ( (dwTextLen = (DWORD)SendMessage(hWnd,WM_GETTEXTLENGTH,0,0)) != 0 ){    if ( (lpCaption = (LPTSTR)malloc(++dwTextLen)) != NULL ){     SendMessage( hWnd, WM_GETTEXT, dwTextLen, (LPARAM)lpCaption );     lpLog->lpAppend->hWnd = hWnd;     lpLog->lpAppend->lpCaption = lpCaption;     lpLog->lpAppend++;     lpLog->dwCount++;    }   }  }  return TRUE; } // 列挙データをクリア VOID EnumStartupEmpty( lpSTARTUPLOG lpLog ) {  lpENUMPROC lpFind;    for ( lpFind = lpLog->lpCurrent ; lpFind->hWnd != NULL ; lpFind++ ){   free( lpFind->lpCaption );   lpFind->hWnd = NULL;   lpFind->lpCaption = NULL;  }  lpLog->lpAppend = lpLog->lpCurrent;  lpLog->dwCount = 0; } // ソート用の比較関数 int compSort( LPCVOID lpData1, LPCVOID lpData2 ) {  HWND hWnd1 = ((lpENUMPROC)lpData1)->hWnd;  HWND hWnd2 = ((lpENUMPROC)lpData2)->hWnd;    if ( hWnd1 < hWnd2 ) return -1;  if ( hWnd1 > hWnd2 ) return +1;  return 0; } // プロセスの列挙 VOID EnumStartupList( lpSTARTUPLOG lpLog ) {  EnumStartupEmpty( lpLog );  EnumWindows( EnumWindowsProc, (LPARAM)lpLog );  lpLog->lpAppend->hWnd = NULL;  lpLog->lpAppend->lpCaption = NULL;  qsort( lpLog->lpCurrent, lpLog->dwCount, sizeof(stENUMPROC), compSort ); } // 続きのプロセスを列挙 VOID EnumStartupNext( lpSTARTUPLOG lpLog ) {  lpENUMPROC lpSwap;    lpSwap = lpLog->lpCurrent;  lpLog->lpCurrent = lpLog->lpPrevious;  lpLog->lpPrevious = lpSwap;  EnumStartupList( lpLog ); } // 最初のプロセスを列挙 VOID EnumStartupFirst( lpSTARTUPLOG lpLog ) {  ZeroMemory( lpLog, sizeof(stSTARTUPLOG) );  lpLog->lpCurrent = lpLog->stData1;  lpLog->lpPrevious = lpLog->stData2;  EnumStartupList( lpLog );  EnumStartupNext( lpLog ); } 以上。

voodoo4500
質問者

お礼

返信おくれて申し訳ありません これでなんとかなりそうです ありがとうございました。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

起動を検索した際に取得したbufを使用して動的にタイトルの配列を作成して管理でしょう char *arTitle[3000] = {0}; int arCnt = 0; arTitle[arCount] = (char*)malloc(strlen( buf ) ); if ( !arTile[arcnt] ) {   // 確保できない場合の処理 } else {   strcpy( arTitle[arCnt], buf );   arCnt++; } 終了した場合の表示に if ( flg != 1 ) {   // 前回以前に表示済みかチェック   if ( arTitle[k] ) {     printf( "%s\n", arTitle[k] );     // 動的確保の後始末     free( arTitle[k] );     arTitle[k] = NULL;   } } といった具合です GetWidnowTextで取得する際に何文字受け取ったかを取得しおいてNULL文字を書き込んでおきましょう nLen = ::GetWindowText( (HWND)arry[i], buyf, sizeof( buf ) ); buf[nLen] = '\0'; といった具合です

voodoo4500
質問者

お礼

ありがとうございます 自分も同じ事をかんがえてましたが、 実現できずこまってました。 どうもありがとうございました。