
No.4ベストアンサー
- 回答日時:
#include <stdio.h>
#include <Windows.h>
// 定数
#define SW_TITLE (1) // タイトルバーの取得
#define SW_CLASS (2) // クラス名の取得
// 独自の構造体を宣言
typedef struct enum_param_t {
LPTSTR lpBuff; // 先頭ポインタ位置
LPTSTR lpTail; // 現在ポインタ位置
LPTSTR lpStop; // 最終ポインタ位置
UINT swOption; // 汎用オプション値
} enum_param_t;
// ウインドウのふるいにかける処理
BOOL MyIsTopWindow( HWND hWnd, LPTSTR lpTitle, LPTSTR lpClass )
{
if ( IsWindowVisible(hWnd) ){ // 可視状態か
if ( GetWindow(hWnd,GW_OWNER) == NULL ){ // トップレベルウィンドウか
if ( lstrlen(lpTitle) > 0 ){ // キャプションを持っているか
if ( lstrcmp(lpClass,TEXT("Progman")) != 0 ){ // シェルでないか
return TRUE;
}
}
}
}
return FALSE;
}
// ちょっとだけ書き換えました。
BOOL CALLBACK EnumWndProc( HWND hWnd, LPARAM lParam )
{
enum_param_t *p = (enum_param_t *)lParam; // ここで構造体を受け取る
TCHAR szWindowName[ 128 ];
TCHAR szClassName[ 128 ];
//ウィンドウテキストの取得
GetWindowText( hWnd, szWindowName, sizeof(szWindowName) );
//ウィンドウクラス名の取得
GetClassName( hWnd, szClassName, sizeof(szClassName) );
// 取得した情報を文字列に取得
if ( MyIsTopWindow(hWnd,szWindowName,szClassName) ){
LPTSTR lpBuff;
// ここで swOption で処理分岐
switch ( p->swOption ){
case SW_TITLE: lpBuff = szWindowName; break; // タイトルバーの取得
case SW_CLASS: lpBuff = szClassName; break; // クラス名の取得
default: return TRUE;
}
// バッファの残り容量をチェック
if ( (p->lpTail + lstrlen(lpBuff) + 1) < p->lpStop ){
p->lpTail += wsprintf( p->lpTail, TEXT("%s\n"), lpBuff );
}
}
return TRUE;
}
// 文字列をクリップボードにコピー
BOOL MyClipboardCopy( HWND hWnd, LPCTSTR lpText )
{
HGLOBAL hMem; // 設定用のメモリ変数
LPTSTR lpBuff; // 複写用のポインタ
DWORD dwSize; // 複写元の長さ
// クリップボードのデータ内容
dwSize = (lstrlen(lpText) + 1); // '\0' 文字分を加算
// データ内容のメモリを確保
if ( (hMem = GlobalAlloc((GHND|GMEM_SHARE),dwSize)) != NULL ){
if ( (lpBuff = (LPTSTR)GlobalLock(hMem)) != NULL ){
// ここでテキストデータを lpBuff にコピー
lstrcpy( lpBuff, lpText );
GlobalUnlock( hMem );
// クリップボードにデータを設定
if ( OpenClipboard(hWnd) ){
EmptyClipboard();
SetClipboardData( CF_TEXT, hMem );
CloseClipboard();
return TRUE;
}
}
GlobalFree( hMem ); // ロックできない時は解放
}
return FALSE;
}
// メイン関数
int main( void )
{
TCHAR szText[ 32 * 1024 ]; // タイトルバー(32 KB)
enum_param_t prm; // 構造体を宣言
// 構造体の初期化
prm.lpBuff = szText;
prm.lpTail = szText; // ここが書き込み位置
prm.lpStop = szText + sizeof( szText );
prm.swOption = SW_TITLE; // 機能拡張用のオプション(自由に値をセット)
// ウインドウの列挙開始
EnumWindows( EnumWndProc, (LPARAM)&prm );
// 特に必要がないなら削除(printf() でも文字列として表示可能)
MessageBox( NULL, szText, "起動中のWindow", MB_OK );
// クリップボードにコピー
if ( !MyClipboardCopy(NULL,szText) ){
printf( "クリップボードにコピーできませんでした。\n" );
}
return 0;
}
以上。
すばらしいです。
動作は、希望通りです。
まだ理解するまでに時間が掛かりそうですが、がんばります。
本当にありがとうございました。
No.3
- 回答日時:
★コールバック関数の lParam を利用すれば良い。
>グローバル変数では無くしたいのですが、コールバック関数で取得した
>szTextをどうすれば、持ってこれるのか?持ってこれないのか?
↑
コールバック関数には第2引数として lParam パラメータを受け取れます。
この lParam に szText のポインタなどを受け取れば良いでしょう。簡単。
>(1)どこの部分でメッセージボックスの表示を行うのか?
> main関数の中です。
↑
了解。
>(2)クリップボードのコピー処理はどこに記述したいのか?
> 独立させた関数にしたいです。
↑
これも了解。
・今は WinMain() で作っていますが main() で良いんですよね。
つまり、コンソール・アプリケーションが完成品のタイプですよね。
次の回答で main() 関数で使えるように全てを書き換えてみました。
・特に EnumWindows() 関数の第2引数とコールバック関数の内部での処理を
今後の参考としてみて下さい。
最後に:
・コールバック関数の中で構造体の swOption を参照すれば列挙するウインドウの
タイプをいろいろと呼び出し元で変更できます。上手く利用して下さい。
次の回答では swOption 変数の参照していませんが構造体メンバにはあります。
・EnumWindows() 関数を実行する前に swOption 変数に何か値をセットしてから
コールバック関数の中で swOption 変数の値により列挙タイプを分ければよい。
・以上。
No.2
- 回答日時:
★上手くいかなかったのですか?
>コールバック関数の中は文字列の取得までとして、
>そのほかは別の関数の中で行いたいのです。
↑
それならコールバック関数の外でサンプルに載せた処理を行えばよいのでは。
・ウインドウ・ハンドル hWnd を指定します。
if ( MessageBox(hWnd,lpText,TEXT("確認"),(MB_ICONQUESTION | MB_YESNO)) == IDYES ){
if ( !MyClipboardCopy(hWnd,lpText) ){
MessageBox( hWnd,
TEXT("クリップボードにコピーできなかった。"),
TEXT("エラー"), (MB_ICONERROR | MB_OK) );
}
}
↑
メッセージボックスを表示したい場所や、クリップボードのコピー処理を行う場所に
上記のサンプルを記述すればよいと思いますけど。
・一応、ソースを補足に貼り付けて見せて下さい。
それから
(1)どこの部分でメッセージボックスの表示を行うのか?
(2)クリップボードのコピー処理はどこに記述したいのか?
(3)コンソール・アプリケーションか?GUI アプリケーションか?どっち。
上記の3つも補足して下さい。
・それではまた。
この回答への補足
たびたびの回答ありがとうございます。
恥ずかしくて、お見せできるようなソースではないのですが、恥を忍んでのせてみます。
szTextにタイトルの列挙をまとめてそれを
呼び出し側の関数で使いたいのです。
今はグローバル変数でやっていてそれなりの結果は出ているのですが
グローバル変数では無くしたいのですが、コールバック関数で取得した
szTextをどうすれば、持ってこれるのか?持ってこれないのか?
どういう、処理が良いのかもあまりわかっていないのが現状です。
(1)どこの部分でメッセージボックスの表示を行うのか?
main関数の中です。
(2)クリップボードのコピー処理はどこに記述したいのか?
独立させた関数にしたいです。
(3)コンソール・アプリケーションか?GUI アプリケーションか?どっち。
多分コンソールです、ウィンドは要りません。
最終的にはメッセージボックスも要らないです。
//////////
//ここでグローバル変数?にしてなんとか出来ている感じです。
char szText[1000] ;
//MyClipboardCopyはそのままここに書きました。
//この辺はweb上のサンプルをかき集めました。
BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam)
{
char szWindowName[128];
char szClassName[128];
//ウィンドウテキスト(キャプション)の取得
GetWindowText( hWnd, szWindowName, sizeof(szWindowName) );
//ウィンドウクラス名の取得
GetClassName( hWnd, szClassName, sizeof(szWindowName) );
//EnumWindows()ではIME等、不可視のウィンドウも全て列挙されるので
//ふるいにかける必要がある
//この辺を弄ると出力を変えられそう by G
//&&はAND ==は同じ
//!=は違う 言う演算子
if( ( IsWindowVisible( hWnd ) ) && // 可視状態か
( GetWindow( hWnd, GW_OWNER ) == NULL ) && // トップレベルウィンドウか
( lstrlen( szWindowName ) > 0 ) && // キャプションを持っているか
( lstrcmp( szClassName, "Progman" ) != 0 )) // シェルでないか
{
//取得した情報を文字列にする
//名前だけで良いのでクラス名は要らない(,szClassName)
//先頭に改行が入ってしまうのを修正
if ( lstrlen( szText ) == 0){
wsprintf( szText, "%s", szWindowName);
}
else{
wsprintf( szText, "%s\n%s", szText,szWindowName);
}
}
return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow)
{
LPTSTR lpText;
EnumWindows(EnumWndProc,0);
MessageBox(NULL, szText, "起動中のWindow", MB_OK);
lpText = szText;
MyClipboardCopy(NULL,lpText);
return 0;
}
No.1
- 回答日時:
★コンソール・アプリケーションですか?
・普通に EnumWindows のコールバック関数内でメッセージボックスの表示や
クリップボードにテキストをコピーすればいいだけです。
・下にサンプルを載せるので組み合わせて使って下さい。
サンプル:
BOOL MyClipboardCopy( HWND hWnd, LPCTSTR lpText )
{
HGLOBAL hMem; // 設定用のメモリ変数
LPTSTR lpBuff; // 複写用のポインタ
DWORD dwSize; // 複写元の長さ
// クリップボードのデータ内容
dwSize = (lstrlen(lpText) + 1); // '\0' 文字分を加算
// データ内容のメモリを確保
if ( (hMem = GlobalAlloc((GHND|GMEM_SHARE),dwSize)) != NULL ){
if ( (lpBuff = (LPTSTR)GlobalLock(hMem)) != NULL ){
// ここでテキストデータを lpBuff にコピー
lstrcpy( lpBuff, lpText );
GlobalUnlock( hMem );
// クリップボードにデータを設定
if ( OpenClipboard(hWnd) ){
EmptyClipboard();
lpBuff = SetClipboardData( CF_TEXT, hMem );
CloseClipboard();
}
else{
lpBuff = NULL; // クリップボードが開けない時は解放指示
}
}
if ( lpBuff == NULL ){
GlobalFree( hMem ); // ロックできない時は解放
}
}
return (lpBuff != NULL);
}
使い方:
LPTSTR lpText; ←コールバック内で取得したタイトル名などが入っているとする。
if ( MessageBox(NULL,lpText,TEXT("確認"),(MB_ICONQUESTION | MB_YESNO)) == IDYES ){
if ( !MyClipboardCopy(NULL,lpText) ){
MessageBox( NULL,
TEXT("クリップボードにコピーできなかった。"),
TEXT("エラー"), (MB_ICONERROR | MB_OK) );
}
}
以上。
この回答への補足
早速の、回答ありがとうございます。
なにぶん、始めたばかりで知識が乏しくうまく説明できませんがご容赦ください。
コールバック関数の中は文字列の取得までとして、そのほかは別の関数の中で行いたいのです。
理由はと聞かれると弱いのですが・・
参考にしたサイトではウィンドにリストボックスを作ってそこに入れていいました。
この所をウィンドを作らずに行いたいのです。
参考にしたURL
http://wisdom.sakura.ne.jp/system/winapi/win32/w …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Visual Basic(VBA) 貼り付けた値が消えていく 以下はソースファイルの2番目のシートのB6から最終行を取得 ターゲットファ 2 2023/07/27 12:23
- JavaScript javascriptのちょっとした動作不良(原因は突き止めたのですが) 1 2023/06/15 19:58
- Visual Basic(VBA) 稀に1円合いません? Sheet1から金額と個数を貼り付ける下記コードで、金額を切り上げるコードを何 3 2022/09/05 15:11
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
count(*)で取得した値をJAVAの...
-
VB.NETで DataRow()を利用して...
-
like演算子内に変数って使えな...
-
ListView 項目の選択/選択解除...
-
JSP+Servletでのページングの常識
-
PHP8でWarning:Undefined varia...
-
JavaScriptにおいてコンピュー...
-
PostgresSQL JDBC で Select結...
-
Excel VBA でログインしてい...
-
VBA:小数点以下の数字を取得で...
-
VB .netにて現在時刻+1時間後...
-
getParameter と getAttribut...
-
ドロップダウンリストの初期表...
-
Yahoo! JAPANのID取得について
-
データ数をカウントしたいのですが
-
利用者側のMACアドレスを取得し...
-
ExcelでNTPサーバーから時刻を...
-
JAVAでWindowsのアカウント名を...
-
VBA Shapesの座標からセル位置...
-
javaで週の最初の日(例:月曜日...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB.NETで DataRow()を利用して...
-
ListView 項目の選択/選択解除...
-
VBA:小数点以下の数字を取得で...
-
VBAでActiveDirectoryのユーザ...
-
Spreadの選択行の取得について
-
PHP8でWarning:Undefined varia...
-
Flexgridで選択行の列の値を取...
-
count(*)で取得した値をJAVAの...
-
VBA Shapesの座標からセル位置...
-
データ数をカウントしたいのですが
-
JavaScriptにおいてコンピュー...
-
利用者側のMACアドレスを取得し...
-
VBA リストボックス内の値を複...
-
like演算子内に変数って使えな...
-
EXCELのリストボックスを選択し...
-
「Excel VBA」 Webクエリ マク...
-
JavaScriptでWindowsログオンID...
-
gethostbyaddrでのホスト名取得...
-
現在時刻をミリ秒まで取得
-
vbaで、オートシェイプ文字幅と...
おすすめ情報