Win32API質問箱 Build47
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2006/11/13(月) 08:56:12やさしいお兄さんやお姉さんたちが答えてくれるかも。
過去スレ、関連リンクは>>2-5くらい。
■注意
・質問する前にMSDNライブラリやPlatformSDK、Google等で検索しましょう。
・日本語版MSDN Online Libraryは不完全です。英語版(http://msdn.microsoft.com/library/)の利用推奨。
・APIフックなど高度な事をしたい場合はできるだけAdvenced Windowsを読みましょう。
・言語特有の問題やIDE、MFCやVCLなどの質問はそれぞれの言語や開発環境スレで
0162デフォルトの名無しさん
2006/11/19(日) 12:16:400163Kioo
2006/11/19(日) 12:25:51今はまだありませんが、ダイアログの下部にボタンをひとつおき、それが押されたら、文字列を変数に入れてダイアログを閉じるようにする予定です
0164デフォルトの名無しさん
2006/11/19(日) 12:36:340165デフォルトの名無しさん
2006/11/19(日) 13:27:57TCHAR* pszText = static_cast<TCHAR*>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(TCHAR)));
GetWindowText(hEdit, pszText, len*sizeof(TCHAR));
// std::string(pszText);
/* 処理 */
HeapFree(GetProcessHeap(), 0, pszText);
半ば定型文
0166デフォルトの名無しさん
2006/11/19(日) 13:32:260167デフォルトの名無しさん
2006/11/19(日) 13:35:320168デフォルトの名無しさん
2006/11/19(日) 14:35:57FILE_FLAG_DELETE_ON_CLOSE だったんですね。ちょっと気が付きませんでした。
0169デフォルトの名無しさん
2006/11/19(日) 15:49:02■MFC相談室 mfc16d.dll■
http://pc8.2ch.net/test/read.cgi/tech/1146117893/
0170デフォルトの名無しさん
2006/11/19(日) 17:14:47終了する時についての質問です。
通常の閉じるをクリックしての終了、
右クリックした時にWM_CLOSEを投げての終了はうまくいくのですが、
ESC(WM_KEYDOWN)が押された時にWM_CLOSEを投げての終了が、
ウィンドウが閉じられるまでに、
CPU率が高くなった状態ですこし止まってしまいます。
原因はどこにあるのでしょうか。
PlaySound(NULL, NULL, 0);はいれています。
また、なぜかMessageBeep(MB_OK);を
抜ける直前に挟むと、ちゃんと終了できます。
0171153
2006/11/19(日) 17:58:24ファイルが削除されません。
何か継承しなければいけないのでしょうか?
0172デフォルトの名無しさん
2006/11/19(日) 18:17:21FILE_FLAG_DELETE_ON_CLOSE法はうまくいかない。
たぶんみんな試さないで書いてると思う。
漏れが昔ここで聞いた方法
1. rundll32で削除用dllを起動する。
2. 削除用dllからアンインストーラの終了を待って消す。
3. FreeLibraryしてから自分自身を消すコードをヒープにコピーして呼び出す。
(ヒープにPAGE_EXECUTEをつけるのをお忘れなく)
0173デフォルトの名無しさん
2006/11/19(日) 19:23:45試さないで書くけど FILE_FLAG_DELETE_ON_CLOSE によるサンプル。
ttp://web.archive.org/web/20051123112406/http://www.numeric.co.jp/Win32.htm
0174デフォルトの名無しさん
2006/11/19(日) 19:34:50> ようにする。
これがポイントか?
0175デフォルトの名無しさん
2006/11/19(日) 19:38:34よくわからんけどそれはハンドルを共用するためだろう。
ハンドルは何で共用する必要があるかというと、
分身起動→本体終了→分身により本体削除
のシーケンスを同期をとって実行するため。
0176153
2006/11/19(日) 20:04:410177デフォルトの名無しさん
2006/11/19(日) 20:31:15試してみたけどやっぱり消えないぞ。
むちゃくちゃコードを補う必要があったからどっかでミスってるのかもしれんが
0178153
2006/11/19(日) 21:09:013. FreeLibraryしてから自分自身を消すコードをヒープにコピーして呼び出す。
(ヒープにPAGE_EXECUTEをつけるのをお忘れなく)
LPVOID pMem = (LPVOID)GlobalAlloc(GMEM_FIXED, size);
DWORD nID;
pMem = VirtualAlloc(pMem, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// pMemにコードをコピー
CreateThread(NULL, 0, pMem, pMem, 0, &nID);
return:
DWORD WINAPI ThreadFunc(LPVOID pMem)
{
// 待ち処理
// 削除
VirtualFree(pMem);
GlobalFree(pMrm);
return 0;
}
こんな感じでしょうか?
0179デフォルトの名無しさん
2006/11/19(日) 21:38:30> pMem = VirtualAlloc(pMem, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
上のGlobalAllocは何のためにあるんだ?
0180デフォルトの名無しさん
2006/11/19(日) 21:38:500181153
2006/11/19(日) 21:41:02GlobalAllocは必要ありませんでしたか。
0182デフォルトの名無しさん
2006/11/19(日) 21:47:50そのレベルじゃ>>172のコードを書くのは無理
0183デフォルトの名無しさん
2006/11/19(日) 21:55:25一時的に無効にする方法を教えてください。
OS は Windows MeとXPです。
0184デフォルトの名無しさん
2006/11/19(日) 22:01:49なメッセージを処理して1を返す
0185デフォルトの名無しさん
2006/11/19(日) 22:06:24問題があったぞ。
>FreeLibraryしてから自分自身を消すコードをヒープにコピーして呼び出す
この手段に対して何も触れてないじゃないか。
0186デフォルトの名無しさん
2006/11/19(日) 22:08:26そもそもそんなとこから教えなきゃならん事態が既に間違ってるってことはわかってるか?
0187デフォルトの名無しさん
2006/11/19(日) 22:09:13教えた側の責任か? それ見てこれ以上付き合う気なくしたんだが。
0188デフォルトの名無しさん
2006/11/19(日) 22:10:40プログラム教室ではない
0189デフォルトの名無しさん
2006/11/19(日) 22:13:33問題があったぞ。
○俺も新人のときCやDOSコマンドを教わった事があるが、この俺様に理解できなかった
のだから常に教えた側の問題に決まってる。
×この手段に対して何も触れてないじゃないか。
○とっとと手段を教えろよ情報を小出しにしやがって使えねーパソヲタども
つーか本当にそこが問題でできないなら聞き返してさえこない時点でオ�hル
0190デフォルトの名無しさん
2006/11/19(日) 22:15:29>・APIフックなど高度な事をしたい場合はできるだけAdvenced Windowsを読みましょう。
0191デフォルトの名無しさん
2006/11/19(日) 22:20:54格下に聞いちまったようだな。
0192デフォルトの名無しさん
2006/11/19(日) 22:23:480193デフォルトの名無しさん
2006/11/19(日) 22:28:02って素直に言えばいいのによ
0194デフォルトの名無しさん
2006/11/19(日) 22:29:550195デフォルトの名無しさん
2006/11/19(日) 22:31:150196デフォルトの名無しさん
2006/11/19(日) 22:34:48知ってるけど、教えてやらない。
0197デフォルトの名無しさん
2006/11/19(日) 23:12:47ttp://www.kumei.ne.jp/c_lang/sdk2/sdk_123.htm
(くメィさん使わしてもらいます)
これじゃないの?やるのは。
0198デフォルトの名無しさん
2006/11/19(日) 23:12:58そんなことぐらい誰でも知ってる。
問題はそこじゃねーよアホ。メモリリークという言葉も知らんのか
> 知らないから教えてください
って素直に言えばいいのに
0199デフォルトの名無しさん
2006/11/19(日) 23:17:04全然関係ない。
つーか>>172でコピー先がヒープであることは本質的じゃない。
別にVirtualAllocでもいいから(むしろMSの推奨はそっちだった気がする)
>>180が何を笑ってるのかよくわからん。
問題は意味もなくGlobalAllocしてメモリリーク起こすようなコードを平然と書く奴に
手取り足取り教えてられるほど暇じゃないってこと。
つーかコードをメモリ上でコピーするやり方はAdvanced Windowsに載ってるんだから
マジで読んでくれ
0200デフォルトの名無しさん
2006/11/19(日) 23:31:39MSがGlobalよりこっち使えって言ってるのは確かHeapAlloc
0201デフォルトの名無しさん
2006/11/19(日) 23:49:05嘘吐け、俺が教えてやったから言えるんだろうが。
最初は頭下げてただろうが下衆野郎。しらねーくせに威張ってんじゃねえよ。
>>199
最初から本でも書いときゃ良いだろうがよ。暇じゃない割に2chにへばりついてやがんな。
0202デフォルトの名無しさん
2006/11/19(日) 23:54:100203デフォルトの名無しさん
2006/11/19(日) 23:58:18>>153
WSHなら自分自身を削除できるし、コマンドプロンプトも出ない。
var fso = WScript.CreateObject("Scripting.FileSystemObject");
fso.DeleteFile("c:\\test.js");
これでアンインストーラを作ったことはないがなw
0204デフォルトの名無しさん
2006/11/20(月) 00:05:47簡易的には使えそう。
どうせならバッチファイルで
0205デフォルトの名無しさん
2006/11/20(月) 00:18:0298以降には一応装備されているから、バージョンが古いけど簡単な操作なら充分かもしれない。
どうしても駄目なら「BATファイルで御免なさい」ですね。
0206デフォルトの名無しさん
2006/11/20(月) 00:27:54WinXP SP2から、VirtualAllocでPAGE_EXECUTE付けて、
その領域のコードを実行できるようにせんと
アクセス違反になるんじゃなかったけ?
たしか、バッファーオーバーフローで任意コードを実行されるのを防ぐためとかだったはず。
ただのデータ置き場ならGlobalAllocでもいいけど。
0207デフォルトの名無しさん
2006/11/20(月) 00:36:24や、バッチファイルだとコマンドプロンプトが出てしまうって話でそ?
まあバッチファイルでも、CreateProcess()でDETACHED_PROCESSで起動すれば
コマンドプロンプトは出ないはず。
0208デフォルトの名無しさん
2006/11/20(月) 00:43:53エクスプローラが立ち上がって、当該ファイルが選択されますが、
これと同じことをするにはどうすればいいんでしょうか?
お願いします。
0209デフォルトの名無しさん
2006/11/20(月) 00:57:40> 最初は頭下げてただろうが
誰に言ってるの? 頭大丈夫?
> 最初から
>>1に書いてるが何か?
0210デフォルトの名無しさん
2006/11/20(月) 01:00:07鏡に向かって話すのが好きなんですね
0211デフォルトの名無しさん
2006/11/20(月) 01:02:28GlobalAllocでもHeapAllocでもスタックでもVirtualProtectでPAGE_EXECUTEを
付けてやれば実行できるようになる。
当然同じページにある周囲のメモリも巻き込まれるのであまりよろしくないけど
0212デフォルトの名無しさん
2006/11/20(月) 01:05:09いやあ仮にそのとおりだとしても
返すものがハンドルだろうがポインタだろうがメモリリークしてることに変わりないし
そもそもGlobalALlocを呼び出す意味自体一切ないと教えてあげてるのに
理解しないばかりか逆切れしてるどっかのバカには負けますよw
0213デフォルトの名無しさん
2006/11/20(月) 01:16:20⌒`γ´⌒`ヽ( E)
( .人 .人 γ ノ
ミ(こノこノ `ー´
)にノこ(
0214デフォルトの名無しさん
2006/11/20(月) 02:11:17遅い(関数の最後)だと エラーがでる。
少しずつreturn 0をずらして書いてみると、ある位置より早ければちゃんとreturnされる。
コンパイル時はエラー0となってて実行時に メモリがreadになれませんでした。となる。
関数のなかで、他の関数を呼びまくってるから呼び出し元がどこだったかを忘れてるのでしょうか?
どうすればいいのやら??
0215デフォルトの名無しさん
2006/11/20(月) 02:15:570216デフォルトの名無しさん
2006/11/20(月) 02:18:11その原因は呼び方の間違いだろうがな。
0217デフォルトの名無しさん
2006/11/20(月) 02:27:04呼び出し規約とかシグネチャが違うとか?
0218デフォルトの名無しさん
2006/11/20(月) 02:34:40return 0; ← 正常に戻る
b();
return 0; ← 落ちる
だと、明らかに b() の中で落ちてるだろ
0219デフォルトの名無しさん
2006/11/20(月) 02:37:19int Kansu{
MessageBox(NULL,"1","めっせじ",MB_OK);
//return 0; //ここならもちろん戻る。
//中略
//中略
MessageBox(NULL,"2","めっせじ",MB_OK); // ここまでの処理は全部やってくれてるのに・・
return 0; //ここで落ちる。"0x33333231"の命令が"0x33333231"のメモリを参照しましただって・・
}
下記のようにダイアログベースのボタんから読んでるだけの超単純なものなのに。
中略部分がややこしいことしてるのでソースは書けないです。
-------------------------------------------------------
case IDC_BUTTON1:
Kansu();
MessageBox(NULL,"もどったよ","よびだしもと",MB_OK);
return TRUE;
-------------------------------------------------------
わからん。 いままでこんなことなかったのに・・。ねるしかないか・・
0220デフォルトの名無しさん
2006/11/20(月) 02:37:200221デフォルトの名無しさん
2006/11/20(月) 02:39:00お笑いですね。。
0222デフォルトの名無しさん
2006/11/20(月) 02:40:21明らかにそこのせいだろ。>>217も言ってるが呼び出し規約が怪しい
0223デフォルトの名無しさん
2006/11/20(月) 02:41:18もう一度言うけどWin32 APIぜんぜん関係ないので
0224デフォルトの名無しさん
2006/11/20(月) 03:11:27デバッガは学習してきます。圧倒的初心者のお相手ありがとうございました。
すみませんでした。
0225デフォルトの名無しさん
2006/11/20(月) 03:16:17そしてとんでもないアドレスにリターンしようとしているのでわ
0226デフォルトの名無しさん
2006/11/20(月) 03:22:381回使い方分かっちゃえばめっさ楽になるからガンバレ
0227デフォルトの名無しさん
2006/11/20(月) 07:29:04WM_**の文字列で取得するAPIがありましたら教えてください。
0228デフォルトの名無しさん
2006/11/20(月) 08:10:360229デフォルトの名無しさん
2006/11/20(月) 08:20:12ありがとうできました。
0230デフォルトの名無しさん
2006/11/20(月) 09:40:32無いよ。自分で変換テーブル作れ。
0232デフォルトの名無しさん
2006/11/20(月) 10:10:31バッチのサンプル
ttp://www.microsoft.com/msj/archive/SF9C.aspx
ここのW32Q0196.zip
FILE_FLAG_DELETE_ON_CLOSEのサンプル
ttp://www.microsoft.com/msj/0198/win320198.aspx
なぜかダウンロードできない。XPでは不調でした。
0233デフォルトの名無しさん
2006/11/20(月) 11:06:10いろいろ見つけたサンプルを元に FILE_FLAG_DELETE_ON_CLOSE
を試行錯誤してみたが、うまくいかなかった。
(例) 98系と2000系で挙動が違う (すまん、どう違ったかは覚えてない)
(例) EXEがネットワークドライブ上だとうまくいかない
で、結局、俺は以下のようにした。
(1) 削除用プログラム(自分自身)を「<GetTempPath()のディレクトリ>\DeleteMe.tmp」にコピー
(2) (1)をMoveFileEx( MOVEFILE_DELAY_UNTIL_REBOOT )で削除予約。
(3) (1)をCreateProcess()、自分自身は終了。
(1)はユーザーがリブートするまで消えないが、ユーザーの目に触れなきゃOK!
0234デフォルトの名無しさん
2006/11/20(月) 11:10:420235デフォルトの名無しさん
2006/11/20(月) 11:12:41試さずに書くが・・・・・
バッチ(command.com/cmd.exe)をSW_HIDEでCreateProcessしては?
0236デフォルトの名無しさん
2006/11/20(月) 13:03:52その方法も良いと思います。
>>234-235
少なくとも ShellExecute ではうまくいきました。
皆さんお世話になりました。お騒がせしました。
0237デフォルトの名無しさん
2006/11/20(月) 13:11:39参考になりました。
0238デフォルトの名無しさん
2006/11/20(月) 20:31:37SendMessageでWndProcへ構造体をわたそうと思っています。
wParamか、lParamにポインタ入れて。
この構造体を入れる領域をHeapAllocでとって、そこに値を入れてSendMessageで渡した後、
WndProcで処理した後、HeapFreeで開放してやりたいのですが、
開放するタイミングはWndProcしかないのでしょうか。
WndProcへwParamとか、lParamでわたってくるマウスの情報とかは、
WndProcで開放しないのでなんかお作法みたいなのがあるように思えますが、
なにか標準のお作法がありますでしょうか。
お作法、または、ドキュメントへの道しるべ等お教えいただけないですか。
0239デフォルトの名無しさん
2006/11/20(月) 20:36:47イベントがWndProcで処理されるまで戻ってこないので、
−メモリ確保
−SendMessage(ここから投げたスレッドはブロック)
−−メインのGetMessageで取得されて、WndProcで処理される
−SendMessageから戻ってくるのでメモリ開放
といった形になるのでしょうか?
とりあえず、AdvancedWindowsの第26章をみてます。
0240デフォルトの名無しさん
2006/11/20(月) 20:43:23SendMessageから帰ってきたところで消せばいい
ちなみにSendMessageはGetMessageで取得じゃなくて、SendMessageが直接プロシージャを呼ぶ
0241デフォルトの名無しさん
2006/11/20(月) 20:51:19>SendMessageで送信したメッセージの処理内でしか使わないのなら
>SendMessageから帰ってきたところで消せばいい
ありがとうございます。
確信がなかったのですが、自信が持てました。
>ちなみにSendMessageはGetMessageで取得じゃなくて、SendMessageが直接プロシージャを呼ぶ
AdvancedWindowsをちゃんとよんでみたら書いてありました。
スレッド間でのSendMessage呼び出しは複雑だと知り、勉強になりました。
ご指摘、ありがとうございました。
0242デフォルトの名無しさん
2006/11/21(火) 00:30:29する状況なら、
>ちなみにSendMessageはGetMessageで取得じゃなくて、
>SendMessageが直接プロシージャを呼ぶ
は間違いだよ。それは同一スレッドの時限定。
0243デフォルトの名無しさん
2006/11/21(火) 01:02:03Advanced Windows読むまで知らなかった。
0244デフォルトの名無しさん
2006/11/21(火) 01:25:560245デフォルトの名無しさん
2006/11/21(火) 10:07:07構造体を渡す側はsizeof(構造体)でこのセットするサイズわかるし渡される側も構造体がわかってるからsizeof(構造体)でとれますよね
0246デフォルトの名無しさん
2006/11/21(火) 10:23:12後で拡張されてサイズが増える場合があるから
最後に char hoge[1] みたいな可変長メンバのプレースホルダがあったりして
sizeof では正しいサイズを得られない場合があるから。
0248デフォルトの名無しさん
2006/11/21(火) 13:40:05そうなると当然構造体のサイズも変わる
おk?
0249デフォルトの名無しさん
2006/11/21(火) 14:27:23同じ名前を流用するより、
OSVERSIONINFO/OSVERSIONINFOEXみたく、
個別に構造体を定義したほうがスマートに見える。
0250デフォルトの名無しさん
2006/11/21(火) 14:31:14MSがそれに気付いてやってくれないとどうにもならないからな・・・
0252デフォルトの名無しさん
2006/11/21(火) 16:41:25一致してれば、な
0253デフォルトの名無しさん
2006/11/21(火) 17:01:43お客さんのPCのGDI32.DLL の類がどんな環境で
いつコンパイルされたかなんか普通わからんと思うぞ。
0255デフォルトの名無しさん
2006/11/21(火) 17:38:04>何の話してるのかね。
Win32 API のヘッダで構造体のメンバに構造体のサイズを設定するフィールドがあるのはなぜ、という話で、
「後で拡張されてサイズが増える場合があるから」という答えに対して
「コンパイル環境とターゲット環境が一致している限りは問題ない」とアフォな返しをする奴がいたので、
ターゲット環境がわかるケースは一般的ではないと指摘してみたんだが・・・
0257245
2006/11/21(火) 17:55:20ビットマップをいじるプログラムをさわったらなんとなくわかってきました。
教えてくれて、ありがとう。
あと、C言語ポインタ完全制覇という本に構造体の一番後ろで拡張するタイプの話がのってたので、
そっちも読んで理解してみます。な〜んでだろっていうのがすっきりして助かりました。
0258デフォルトの名無しさん
2006/11/21(火) 18:37:27ヘッダを開いて、それぞれの構造体の宣言部を見てみるのもいいと思うぞ
#ifdef _WIN_VER〜#endifとかあるから
0259デフォルトの名無しさん
2006/11/21(火) 18:47:33C言語をベースに勉強していて、
テキストエディタを作っています。
コモンダイアログの「検索」を出して、
エディタ内の文字列を探す所まではなんとかできたのですが、
その結果をエディタに表示する方法がよくかりません。
エディタの内容をchar配列に移して、
そこからstrstrで検索して、
見つかったら戻り値のポイントを調べて、
SendMessage(MyDataGet_hEdit(), EM_SETSEL,[戻り値], [戻り値 + 検索文字数]);
で結果を明示しようとしています。
見つかった文字列がエディタ内に表示されている状態ならば、
これでもよさそうなのですが、
表示されていない場合、スクロールを自分で動かして、
どこが選択されているか調べないといけないという、
検索した意味のない状態になってしまっています。
どうしたら普通の検索のように、
検索結果(選択状態の文字列)まで、
画面表示を自動スクロールさせられるのか、ヒントをください。
ターゲット環境が「分かる」必要なんか無いだろ。
ターゲット環境は「作るときに決める」物なんだから。
「ターゲットを決めうちする限りは問題ない」とする回答に「ターゲットが分からない」と
返す方がよっぽどAFOだと思うが。
0261デフォルトの名無しさん
2006/11/21(火) 19:08:290262デフォルトの名無しさん
2006/11/21(火) 19:29:22biSizeは言ってみれば構造体のバージョンナンバー。
BITMAPINFOHEADER, BITMAPV4HEADER, BITMAPV5HEADERのように
構造体が拡張された場合に、API側がbiSizeを見てどの構造体なのか
判断している。
これのおかげで、BITMAPINFOHEADERを要求するAPIにV4やV5の
構造体を渡すことができる。
■ このスレッドは過去ログ倉庫に格納されています