トップページ⇒tech
1001コメント295KB

Win32API質問箱 Build18

■ このスレッドは過去ログ倉庫に格納されています
0001 ◆Manna2uCLg NGNG
スレ立てるまでもない、Win32APIについての質問はこちらへどうぞ。
やさしいオジサマ達が、熱く暑く答えてくれよう。
でも最低限、最新スレくらいは質問する前に検索を。
過去スレ・参考は>>2-5くらいを参照するッス!
0237232NGNG
>>235
ありがとうございます。調べてみます。
0238232NGNG
リロードしてなかった。

>>236
詳しくありがとうございます。直してみます。
0239232NGNG
あっ、そもそも大きな勘違いをしていました。
StretchDIBitsの時に表示していると思っていました。
TextOutと違い、ShowBitmapなどの名前でないのは、
その場で表示するわけではないからですね。
0240デフォルトの名無しさんNGNG
bigenPaint()したんだけどヘヤーカラーしか変わりません
0241デフォルトの名無しさんNGNG
>>240
そうなる仕様でつ。
0242232NGNG
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
for(y = 0; y < 10; y++)
for(x = 0; x < 10; x++)
ShowBitmap(hwnd, hdc, SHOW_BITMAP, y * 16, x * 16, 1, 1);
EndPaint(hwnd, &ps);
break;
こんな感じにしたら出来ました。

後、GetDCに変えてみると何回もWM_PAINTに行っているみたいで
CPU率がえらい事になっていましたが、return DefWindowProcを
defaultの所に書かずに関数の最後の所に書いたら直りました。
(どのイベントの時でもDefWindowProcを通るようにする)

しかし、ウィンドウズアプリケーションは難しすぎます。
いったいどのやり方でやるのが一番いいのでしょうか。
0243デフォルトの名無しさんNGNG
>>242
こういうやり方をするなら、フレームバッファを構築してそっちで書き換えた方がいいと思われ。
WM_PAINT内は、フレームバッファの内容をBitBltなどで展開するのみに徹した方がいい。
あと、ここまでやりたいのかどうかは知らないけど、途中で画像を書き換えたい場合は、
WM_PAINTメッセージを起こすのではなくGetDCを取得して張り付ける方がいい。
これで、大分負担は減るんじゃないかな。

しかしながら、CPU使用率を考えるくらいなら、まずWindowsプログラムを覚えることを
優先した方がいいんじゃない?
0244232NGNG
>>243
ありがとうございます。
初心者なので何となくは分かるのですが難しいです。
仰るように基本の部分から勉強します。
0245デフォルトの名無しさんNGNG
コールバックで特定のHWNDの時のみ処理したい場合どうすればいいのでしょう。
ウィンドウが一つのときは大丈夫だと思うのですが。
0246デフォルトの名無しさんNGNG
分岐にはif文を使う
0247245NGNG
>>246
ええとそういう事ではなくて。説明不足ですね。
WinMainで"hoge"と"foo"という2つのウィンドウを作ったとき、
どちらのウィンドウにイベントが起こっても同じコールバック関数で
受け取るので、そのときHWNDが"hoge"のHWNDか"foo"のHWNDかを
判断したいのです。
例えばif(strcmp(CheckHWND(hwnd),"hoge")==0)みたいな感じです。
0248デフォルトの名無しさんNGNG
HWNDじゃ無理です。
0249デフォルトの名無しさんNGNG
>>247
ちょっと考えれば解ると思うが、あんたの方法だと、何らかの方法でイベントの発生したウィンドウのHWNDを得なければならない。

で、「イベント」とはなんだ?
0250246NGNG
>>247
SetPropとかすればいいんじゃに?

>>249
ウィンドウプロシージャがよばれるんだろ
0251245NGNG
>>248
何ならできますか。

>>249
イベントとは左クリックとかのWM_**です。

実はひとつのウィンドウ毎にひとつのコールバック関数を作るもの
なんですかね。myProg.lpszClassNameとCreateWindowの第一引数、
myProg.lpfnWndProcとコールバック関数の名前を同じにしますが、
それを2つのウィンドウで別々にすれば、自然と"hoge"でのイベントは
hogeCallへみたいになるんじゃないかと。
実はまだ複数のウィンドウのプログラムを作ったことが無かったので、
実験をすることも無くどうなるんだろうと質問してしまいました。
0252デフォルトの名無しさんNGNG
>>251
定石的にはMFCやATLがやってるように(それぞれ多少手段は違った気がするが)
ウィンドウと対応するC++なりのオブジェクトをつくってウィンドウ毎に処理を分ける。
0253159NGNG
SHChangeIconDialogに関して質問いれたものです。
iconインデクス取得して絵画まではいけますたが

引数で送ったpath以外のディレクトリを参照で選ばれた場合の
pathをうけとる方法がわかりませぬ。

どなたかご教授願います。
0254245NGNG
>>252
やっぱウィンドウが複数あったり、長編なプログラムは、
MFCとかで作るもんなんですかね。自分はMFCに挫折したくちでして。
SDKのみで作っている所で創プロはすごく参考になるのだけど、
やさしめのなので(それでも難しい)。
0255デフォルトの名無しさんNGNG
>>253
VBでいいのかな? 漏れの作ったのでよければ。

Private Declare Function SHChangeIconDialogA Lib "shell32" Alias "#62" (ByVal hWnd As Long, ByVal szFilename As String, ByVal Reserved As Long, lpIconIndex As Long) As Long
Private Declare Function SHChangeIconDialogW Lib "shell32" Alias "#62" (ByVal hWnd As Long, ByVal szFilename As Long, ByVal Reserved As Long, lpIconIndex As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Function ChangeIconDialog(ByVal hWnd As Long, strPath As String, Optional Iconidx As Long = 0) As Boolean
Const MAX_PATH As Long = 260
Dim strBuf As String * MAX_PATH, strRet(MAX_PATH) As Byte
Dim lPtr As Long, lRet As Long

strBuf = strPath & vbNullChar
If IsWinNT() Then           ←OSがNTかどうか判断。自分で作る
  lPtr = StrPtr(strBuf)
  lRet = SHChangeIconDialogW(hWnd, lPtr, MAX_PATH, Iconidx)
  CopyMemory strRet(0), ByVal lPtr, MAX_PATH
  strBuf = CStr(strRet)
Else
  lRet = SHChangeIconDialogA(hWnd, strBuf, MAX_PATH, Iconidx)
End If

If lRet Then
  ChangeIconDialog = True
  strPath = Left$(strBuf, InStr(strBuf, vbNullChar) - 1)
End If
End Function

呼ぶときは
Call ChangeIconDialog(Me.hWnd, パス, インデックス)
パス、インデックスに変更された値が戻ってくる。
0256246NGNG
>>254
おまえ俺を馬鹿だと思ってるだろ
0257デフォルトの名無しさんNGNG
MFCで無理なのにSDKで作れるって言うのはいったい・・・
0258デフォルトの名無しさんNGNG
WindowsXP sp1 Visual C++

Wininetを使った汎用的なクラス(class Internet)を作りたいんだけど、
アプリケーション定義コールバック関数とInternetSetStatusCallbackへ渡すコールバック関数を使うと
コンパイル時に「warning C4312: '型キャスト' : 'DWORD' からより大きいサイズの 'Internet *' へ変換します。」
と出て、実行するとハンドルされていない例外が出て止まってしまうんだけど問題なく動かす為にはどうしたいいんだろう?

こんな感じ
//アプリケーション定義コールバック関数
virtual void callback( DWORD dwStatus, LPVOID lpStatusInfo );

//InternetSetStatusCallbackへ渡すコールバック関数
static void CALLBACK _inet_callback( HINTERNET hInternet, DWORD dwContext, DWORD dwStatus, LPVOID lpStatusInfo, DWORD dwStatusInfoSize)
{
( (Internet*)dwContext )->callback( dwStatus, lpStatusInfo );
}
0259245NGNG
>>256
とんでもございません。
>>247の書き方に失礼があったのならここでお詫び申し上げます。

>>257
使い方が分からないんです。猫のリソース・スクリプトも分かりません。
VBも挫折しました。ソースだけで作れるのでないと分からないです。
0260デフォルトの名無しさんNGNG
>>259
じゃぁ、一緒にC#勉強しませんか?
割と良い感じですよ。
MFCの嫌だったところが全てなくなってる。
0261デフォルトの名無しさんNGNG
グローバル変数に記録しとけばいいだけの話だろ。
何を悩む必要があるんだ?

hWnd1 = CreateWindow();
hWnd2 = CreateWindow();

WndProc()
{
if (hWnd == hWnd1) {
...
}
else if (hWnd == hWnd2) {

}
}
0262デフォルトの名無しさんNGNG
糞プログラマが現れた
○戦う
○逃げる
0263デフォルトの名無しさんNGNG
たぶん>>259さんはメッセージ駆動に慣れていないだけだと思うんですよね。
C#からはじめればばっちりですよ。
0264159NGNG
>>255
VBでOKなんです。こちらの意図が完全にとおりました。
どうもありがとうございます。

ってかめちゃコード見やすい・・・見習わないと・・・
0265245NGNG
>>260
C#ですか。どんな感じなのかいろいろ調べてみます。
ただ自分は、新しいのを覚えようとしないで、今ある知識で
工夫して何かを作ろうと考えてしまう所があって、
そのままSDKで作るかもしれませんが、その時はすいません。

>>261
グローバル変数はいけないという概念があって。WinMainは
スタートファイルだから、externとかしなくてもいいので
逆に使うことで困ることは無いと思うのですが。
0266デフォルトの名無しさんNGNG
よしここらでいっちょ指摘しとこう。
×教授 ○教示
0267245NGNG
>>263
ええ、全然慣れていません。
ゲームを作ろうと思ったのですが、コンソールアプリでは
表現しきれないので、グラフィックを使いたいと思って、
勉強を始めました。昔少しやったことはあったのですが。
正直うざいだけです。PeekMessage+Sleepのメインループで
グルグルがいいのですが、勉強するチャンスでもあるのでやってます。

C#はいいんですかね。文章を読んだだけで2人の方が進めてくれたので
まさに自分にぴったしのなのかもしれません。
0268デフォルトの名無しさんNGNG
きょうじゅ けう― 【教授】

(名)スル
(1)0 1 (ア)児童・生徒に知識・技能を与え、そこからさらに知識への興味を呼び起こすこと。
(イ)専門的な学問・技芸を教えること。
「国文学を―する」「書道―」
(2)0 大学などの高等教育機関において、専門の学問・技能を教え、また自らは研究に従事する人の職名。助教授・講師の上位。


いいんでない?
0269デフォルトの名無しさんNGNG
>>265
ならstaticにすればいいじゃない。
変数名直で書くのがいやならクラスメンバにするとか。
形体はなんであれ、スタック以外の領域に、なんらかの形で
ハンドルを覚えておかないと分岐のさせようがないのはわかるでしょ?
0270245NGNG
>>269
そうですね。CheckHWNDみたいな関数があったとしても
もう片方の辺が無いから意味ないですし。
そういえば猫プロ(だっけ?)も始めに
char szClassNme[] = "ウィンドウクラス・ネーム" ;
みたいにWinMainの前にグローバル変数で書いてありますね。
0271デフォルトの名無しさんNGNG
もしや盲信的にグローバルは駄目といっているだけなのか?
0272245NGNG
>>271
そうだと思います。
ただ、長編のときはグローバル関数をあまり使わないで、
カプセル化(だっけ?)した方がよかったりするように、
極力使わないほうがいいのは分かっています。
ただ、逆に使わないと大変な所は、無理せず使うようにします。
0273デフォルトの名無しさんNGNG
>>272
まーそれでいいんじゃない。事情がわからんので適当だけど
普通は>>261よりは>>251のアプローチだと思うよ
0274デフォルトの名無しさんNGNG
すみません、質問させてください。

ウィンドウのタイトルバーの左側にあるアイコンを動的に設定する方法ってありますか?
今、
hIcon = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 0, 0, LR_CREATEDIBSECTION);
DrawIcon(GetDC(hWnd), 0, 0, hIcon);
などとやっていたんですが、
これはアイコンの設定ではなくて描画ですよね……。

WNDCLASS を毎回 RegisterClass() して対処しようかとも思ったのですが、
直前に RegisterClass() した時の WNDCLASS を取得する方法もわかりませんでした。

何か解決策はありませんか?
0275デフォルトの名無しさんNGNG
>>274
WM_SETICON
0276デフォルトの名無しさんNGNG
>>274
WM_GETICON?
0277デフォルトの名無しさんNGNG
今C#いじってるけど、想像より実行が速いんで驚いてるよ。
ただ、俺のやり方が悪いんだろうが、すぐAPIが恋しくなってDllImport使いまくってる。
0278274NGNG
>>275
おお! あっさりできました!
ありがとうございます!

>>276
おはようございます。
0279デフォルトの名無しさんNGNG
>>277
.NET Frameworkのメモリ馬鹿食いはきにならない?酷すぎるんで結局W32APIに戻ってきたよ
0280デフォルトの名無しさんNGNG
>>277
実行中の重さは(GUI使わなければ)気になることはないね。
0281デフォルトの名無しさんNGNG
.NET Frameworkでアプリのローカライズをやっちゃうと、
他の開発環境に戻りたくなくなってしまいますた。
0282258NGNG
>>258の現象はvirtualをつけるとなるみたいです。
virtualをつけても大丈夫な方法はあるんでしょうか?
0283デフォルトの名無しさんNGNG
>>279
元々でかくなるプログラムを書いてるんで、メモリ消費量は気にならない。
むしろ今は、未知の言語を触っているという楽しさがあるので、
使い慣れてきたら気になってくるかもしれんけどね。
0284デフォルトの名無しさんNGNG
>>277
実行は早いね。
メモリーが気になるのも同意。
マイクロソフトがこれを主流にする気みたいだから、
これで行っても大丈夫だろうとは思う。
0285デフォルトの名無しさんNGNG
Cでやってるんですけど、MIDI再生ができませぇん。
コンパイルはできるけど、音がでない・・・OTZ

http://www.users.yun.co.jp/~studiowing/win32api/win-17.htm
ここの使ってるんですけど、何か注意する事とかありますか?
0286デフォルトの名無しさんNGNG
えらく大雑把なサンプルだなw
まあそれは良いとして、mciSendString の戻り値は確認したのか?
それなりのエラーコードが返ってるんじゃないか?
0287デフォルトの名無しさんNGNG
Windowsアプリケーションでコマンドライン引数を取得する処理を
自前でやってるので大変です。
main関数を使ったときのargc, argvみたいに
簡単に取り出せるAPIはないですか?
0288デフォルトの名無しさんNGNG
__argc __argvじゃいかんの?
0289デフォルトの名無しさんNGNG
>>288
おぉ。そういうのがあったのですか。
調べてみます。ありがとうございます。
0290デフォルトの名無しさんNGNG
__argc, __argvだっけ?
0291デフォルトの名無しさんNGNG
リロード忘れてた(鬱
0292デフォルトの名無しさんNGNG
>>290
うん。

>>291
(,,゚Д゚) ガンガレ!
029354NGNG
>>56-58
ありがとん。返事が遅くなってスマソ。

>>58さんのGDI+で問題解決しました。
ttp://www.kumei.ne.jp/c_lang/sdk4/sdk_336.htm
0294デフォルトの名無しさんNGNG
>>285
MIDIファイルの位置が悪いとか……
実行ファイルのあるフォルダにMIDIをおいて、VSを使わずに直接実行してみても駄目?
0295232NGNG
>>232です。
ビットマップを普通に表示するのは分かってきたのですが、
透過の仕方がわかりません。調べるとマスクとか書いてあるのですが分かりません。
以下のプログラムなら、どう発展させていけばいいのでしょうか。
http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=1060403548&res=61&fi=no
0296232NGNG
>>295
すいません。ShowBitmap関数のStretchDIBitsの最後の引数を
dwRopに変更してください。

後、実はその変更を行った後、たまたま人(前景)のほうの引数を
SRCANDにしたら透過できてしまいました。
SRCANDは「論理 AND 演算子を使って、コピー元の色とコピー先の色を
組み合わせます。」らしいのですが、なぜ透過できたのでしょうか。
0297デフォルトの名無しさんNGNG
今日は、Charles Petzoldの刺青に萌えました・・・
ttp://www.charlespetzold.com/
0298232NGNG
すいません。>>295-296は人が黒のみだからうまく出来てたようです。
いろいろ調べていましたが分からないので、
1ピクセルずつ調べながら透過しない位置をGetPixelとかで
描画する方法でやってみます。お騒がせしました。
0299デフォルトの名無しさんNGNG
>>298
そこでなんで"たまたま"成功したかを追求すれば正解があるんだが。
0300232NGNG
>>299
自分はウィンドウズの基礎がなってないので難しいです。

一応>>298の方法で256色のはできました。
ただintのカウンタとforを使って普通にやっているので
表示するサイズが大きくなるとかなり遅そう。
0301デフォルトの名無しさんNGNG
>>298

1ピクセルずつやる、というのは妥当な方法だけど(マスク作るよりは楽)
それをやるならビットマップのメモリデバイスコンテキストに対してでは
なくDIBピクセル列に対して行うべきだね(DIBの操作は単純なメモリアク
セスなので、処理が圧倒的に早く正確)。

性能的には32ビットDIBで数百×数百ピクセルのビットマップを透過処理
しても、特に問題はない。
0302デフォルトの名無しさんNGNG
>>300
> ただintのカウンタとforを使って普通にやっているので
> 表示するサイズが大きくなるとかなり遅そう。

そういうもんです。
あとは、GetPixelみたいに1ピクセルごとに計算するのではなく、301さんが言うような方法で
メモリ上に展開することでループ計算や関数呼び出しのフィードバックを省略したり、
直接アセンブラをいじってMMXやSSEを呼び出し、数ピクセル分を一気に計算したりすることで
高速化を図ったりする。
0303デフォルトの名無しさんNGNG
斜体フォント文字の表示長方形領域を取得したいのですが、
DrawText(hDC, str, -1, &rect, DT_CALCRECT);
では、通常フォント文字の表示長方形領域を返してきます。

斜体フォント文字の表示長方形領域を正確に取得する方法をご存知の方、
教えていただけないでしょうか?
0304232NGNG
>>301>>302
以下を>>295のプログラムのStretchDIBitsを消して
その位置に加えれば透過描画が出来ます。(8ビットのみ)
透過の位置はビットマップの左上と同じ色の位置です。
どこを直すといいでしょうか。
if(bmpInfo->bmiHeader.biBitCount == 8) //256色ビットマップ
{
int i ;
int updw = bmpInfo->bmiHeader.biHeight > 0 ? 1 : -1; //up,downどっちの方式か
int sizeX = bmpInfo->bmiHeader.biWidth; //サイズx
int sizeY = abs(bmpInfo->bmiHeader.biHeight); //サイズy
int dot = sizeY * sizeX; //ドット数
int p; //パレットの種類
int x, y; //拡大をしない表示する位置
int x2, y2; //拡大の分
int touka = updw > 0 ? lpBMP[dot - sizeX] : lpBMP[0]; //透過する色のパレットの位置
for(i = 0; i < dot; i++)
{
p = lpBMP[i];
if(touka == p)continue; //透過する位置
x = (spotX + i % sizeX) * bairituX;
y = (updw > 0 ? spotY + sizeY - i / sizeY - 1 : spotY + i / sizeY) * bairituY;
for(x2 = 0; x2 < bairituX; x2++)for(y2 = 0; y2 < bairituY; y2++)
SetPixelV(hdc, x + x2, y + y2,
RGB(bmpInfo->bmiColors[p].rgbRed, bmpInfo->bmiColors[p].rgbGreen,
bmpInfo->bmiColors[p].rgbBlue)); }}
0305デフォルトの名無しさんNGNG
>>303
GetTextExtentPoint32はどう?
0306303NGNG
>>305
ダメでした。
DrawText(hDC, str, -1, &rect, DT_CALCRECT);
と同じ結果でした。
0307デフォルトの名無しさんNGNG
>>306
hDCにフォントの指定はしてあるよね…?
0308306NGNG
>>307
指定してます。
OldFont = (HFONT)SelectObject(g_mem.hSzDC, hfont);

ワードパッドで斜体文字を表示して、選択で色を反転した時にわかる領域サイズと
同サイズが返ってきていると思われます。
Win32APIでは、斜体文字の表示範囲を取得するのは無理なのでは?
と思いはじめています。
0309デフォルトの名無しさんNGNG
>> 308
私もやり方を知らない。
それらプラス tmOverhang が助けにならないのは知ってる。
GetCharABCWidths, GetCharWidth32, GetCharPlacement, GetGlyphOutline
あたりはためしてみた?
0310 ◆IGEMrmvKLI NGNG
VBからAPIをコールしています。
InternetConnectをコールしているのですが、そのあと、アプリケーション終了時に
応答が帰ってこなくなることがあります。
マシンによって違い、アプリケーション終了後、正常終了して普通に終わるマシンと
アプリケーション終了後、正常終了して、タスクに応答なしで残りつづけるもの。

InternetConnect関数コール直後、デバッカによる停止で上記事象が発生するので、
そのあたりだとは思うのですが、OSによっての違いでもないみたいですし。

環境は、VB6.0SP5
Window2000 SP4
です。

応答が帰ってこない事象は、今のところ、Win2kSP3とSP4で確認しています。
逆に、通常に終わる場合は、WinXP・Win2kSP3・SP4・WinNTなどで確認しています。

原因について、思い当たるような節のあるかた、いらっしゃいましたらご教示よろしくお願いします。
0311デフォルトの名無しさんNGNG
>>310
で、結局Win2kSP3・SP4ではどういう挙動を示すんだ?
0312310 ◆IGEMrmvKLI NGNG
すいません。解決しました。
Win2kSP3・SP4の場合、タスクマネージャーに応答なしアプリケーションとして、
30秒程度?居残りつづける状態でした。

原因ですが、FTPサーバへのログインにAnonymousを使用していると、
同様の事象が発生するようです。
ほかのユーザを切りなおしてそのユーザでログインすると、その事象は解決しました。

どうも、ご迷惑をおかけしました。
0313デフォルトの名無しさんNGNG
プロセスハンドルからプロセスIDって取れませんか?
ShellExecuteEXでプロセスハンドルしか帰ってこないんです。
0314デフォルトの名無しさんNGNG
>>313
GetProcessId()でいいんじゃないの。
XP sp1 以降なら。
0315デフォルトの名無しさんNGNG
>>313
CreateProcessを使うとプロセスIDを取得出来るねぇ。
0316デフォルトの名無しさんNGNG
>>313
GetWindowThreadProcessIdというのもあるよ。参考までに。
0317313NGNG
>>314
XP sp1以降ということは、それ以前では感嘆には取れないんでしょうか?

>>315
データファイルを関連付けアプリで起動したいので、ShellExecute(EX)が
いいんです。
CreateProcessだとEXE直接起動オンリーですよね。FindExecutableで
さがせますけど、openのほかにprintとか他のverbもサポートしないと
いけないかも、なのでレジストリ直読みして環境変数置き換えて・・・・
マンドクセ

>>316
それだとウィンドウハンドルがわかんないといけないですけど、
プロセスハンドルからそのプロセスのウィンドウハンドルって取れます?
プロセスIDが分かっているときにウィンドウハンドルをとるなら
EnumWindowsとGetWindowThreadProcessIdで出来るんですが・・・
そのプロセスIDがわからんわけです。
0318デフォルトの名無しさんNGNG
この辺が参考になるかな。

ttp://search.acty-net.ne.jp/mfc_search/archive/2001-1/msg03531.html

プロセスハンドルはシステム内で一意な値じゃないからそこから
プロセスIDを特定することは出来ないってことじゃないかな。

手間を惜しまないのなら、SetWindowsHookExかCreateRemoteThreadで
対象プロセスに自作のルーチンを進入させてGetCurrentProcessIdする手が
あるけど。
0319デフォルトの名無しさんNGNG
NtQueryInformationProcess
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/ntqueryinformationprocess.asp

Windows2000 と WindowsXP (SP適用前) の場合限定で使えるんでない?
WindowsXP SP1 以降は GetProcessId() を使う方向で。
WindowsMe 以前は諦め…
0320デフォルトの名無しさんNGNG
>>319
9xでは構造体を直接読むという荒業が使えると思われ
どうせ9xはdisconなのだから将来の互換性の問題は気にする必要ないし
0321デフォルトの名無しさんNGNG
キャレットの表示にCaret系使うのと自分でInvertRectとかで描くのと何が違うんですか?
0322デフォルトの名無しさんNGNG
CreateToolhelp32Snapshotでどう?
0323デフォルトの名無しさんNGNG
Taking a Snapshot and Viewing Processes
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/taking_a_snapshot_and_viewing_processes.asp
0324デフォルトの名無しさんNGNG
で、便乗して質問なんだけど、SetWindowsHookExで全スレッドにフック取り付ける場合、
data_segとか使って全DLLで同じメモリ領域(HHOOKとか)を参照するようにしますよね?
でもそうすると、SetWindowsHookExを複数回呼ばれた場合に、
つまりSetWindowsHookExを含むDLLが複数のプロセスで呼び出された場合、
重複したフックが設定されてしまう可能性があります。

また、肝心のフック関数は処理結果を指定されたウィンドウハンドルに送るわけですが、
上記DLLを排他処理した場合、1つのウィンドウハンドルにしか送れなくなってしまいます。

これら問題を上手く解決する方法はないものでしょうか?

つまり、
SetWindowsHooExを呼び出す関数は、どのタイミングでどのプロセスから呼び出されても、
安全・確実に実行する事が出来き、かつその全ての呼び出し元が要求したウィンドウハンドルに、
全ての呼び出し元が開放を要求するまで、フック関数からのメッセージが確実に送信される、
というふうにしたいのです。
0325デフォルトの名無しさんNGNG
どっかでも以前議論してたが、フックハンドルを共有メモリ領域に置く必要は無かった筈
0326デフォルトの名無しさんNGNG
>>325
すみません。"フックハンドル 共有メモリ"でググってみましたが、見つかりませんでした。
共有メモリ領域を使わない方法とはどのようなものなのでしょうか?
0327デフォルトの名無しさんNGNG
http://pc.2ch.net/tech/kako/991/991576947.html
にそれらしきレスがありますが、
CallNextHookExにNULLを渡すというのはソースが見つかりませんでした。
0328デフォルトの名無しさんNGNG
>>325
それでも一応動くけど
CallNextHookExで正しいフックハンドルを渡さないと環境によってはシステム自体が著しく不調になる
0329324NGNG
現在のソースはこんな感じ:
HANDLE hMutex = NULL;

hMutex = ::CreateMutex( NULL, TRUE, SYSTEM_HOOK_MUTEX_NAME );
if ( hMutex == NULL ) {
// exception
}

if (::GetLastError() == ERROR_ALREADY_EXISTS) {
DWORDdwWaitResult;

dwWaitResult = ::WaitForSingleObject( hMutex, 1000 );

if (dwWaitResult != WAIT_OBJECT_0) {
// exception
}

}

g_hMouseHook = ::SetWindowsHookEx(
WH_MOUSE,
(HOOKPROC)g_MouseProc,
hinstDLL,
0
);

if (g_hMouseHook == NULL) {
// exception
}

::ReleaseMutex( hMutex );
0330デフォルトの名無しさんNGNG
>>329を見たら腹が痛くなってきた
0331デフォルトの名無しさんNGNG
俺はどっちかっていうと腹が減ってきた
0332デフォルトの名無しさんNGNG
俺なんて最近腹が出てきた
0333デフォルトの名無しさんNGNG
つまんねーレスに腹がたってきた
0334デフォルトの名無しさんNGNG
はらたいらさんに1000点
0335デフォルトの名無しさんNGNG
同じグローバルフックを複数使う理由がわからん
0336324NGNG
>>335
フックを使用するプログラムが、
ユーザ意思によって多重起動される可能性がある場合。
■ このスレッドは過去ログ倉庫に格納されています