Win32API質問箱 Build124
■ このスレッドは過去ログ倉庫に格納されています
Win32APIについての質問はこちらへどうぞ。
■注意
・質問する前にMSDNライブラリやPlatformSDK、Google等で検索しましょう。
・日本語版MSDN Online Libraryは不完全です。
英語版( http://msdn.microsoft.com/en-us/library/ )の利用推奨。
・APIフックなど高度な事をしたい場合はできるだけAdvenced Windowsを読みましょう。
・言語特有の問題やIDE、MFCやVCLなどの質問はそれぞれの言語や開発環境スレで
■過去スレ
Win32API質問箱 Build123
http://mevius.2ch.net/test/read.cgi/tech/1475897582/
Win32API質問箱 Build122
http://echo.2ch.net/test/read.cgi/tech/1451988219/
Win32API質問箱 Build121
http://echo.2ch.net/test/read.cgi/tech/1438695290/
Win32API質問箱 Build120
http://echo.2ch.net/test/read.cgi/tech/1428570962/
■関連スレ
Visual Studio 2017 Part4
http://mevius.2ch.net/test/read.cgi/tech/1509244956/
【C++】 DirectX初心者質問スレ Part40 【C】
http://mevius.2ch.net/test/read.cgi/tech/1474782237/ Win32API標準 のリストビュー(クラス名 SysListView32) 上のリストアイテムに対して、keybd_event()やmouse_event() を使わずに
プログラムからキー押下やクリックのイベントを起こすにはどうしたらよいですか。 SendMessage(hLV, WM_LBUTTONDOWN, ...);
SendMessage(hLV, WM_LBUTTONUP, ...); LVM_ENSUREVISIBLE
LVM_GETITEMRECT >>10,11
スレの性質上、意味のない無駄な書き込みはやめてもらえますか。お願いします。
意味もなくAPI名やキーワードを羅列することは、情報が冗長になりスレの価値を下げることになります。 >>9
LVM_ENSUREVISIBLEメッセージで、リストビューの項目を表示させる。
LVM_GETITEMRECTメッセージで、項目の位置を取得する。
取得した場所に対して、WM_LBUTTONDOWN/UPメッセージを呼ぶ。 >>13
リストビューにフォーカスがない状態でWM_LBUTTONDOWN/WM_LBUTTONUPを2回送信して、
ダブルクリックが仮想的に実行できるか試してみましたが、選択位置(フォーカスがないので灰色)が変わるだけで反応なしでした。
WM_LBUTTONDBLCLKだと灰色位置の変化もなし。
WM_LBUTTON*系のメッセージを使わない正規の方法があるかと思ったのですが、なさそうですね。
回答ありがとうございました。別の方法考えます。 クライアント座標とスクリーン座標があって、クライアント座標系はウィンドウごとに場所が違うから注意が必要だ。 >>18
当方、送信したい相手はdllから読み込んだ同一プロセス上のリストビューなので、GetWindowLongPtr(GWLP_WNDPROC)でイベントをフックして使った。
NM_DBLCLKイベント自体はフックしたプロシージャにちゃんと送られていることは確認できた。
NM_DBLCLKイベント送受信は成功したが、期待するダブルクリック時の振る舞いをしてくれないので、求めていた機能は成功していない状態。
これ以上はdll側の実装依存との格闘になるので、ここでの質問は終わらさせていただきます。 ダブルクリックには常に先行するシングルクリックがあるとか2回目のシングルクリックもあるとかちゃんとやってるよね ダブルクリック処理面倒くさい
ドライバーレベルで峻別してくれないかな
ところでGetDoubleClickTime()にあわせてタイマーイベントすると
体感長く感じるんだがどう処理するのが正しいのかな ブラウザゲームとかダブルクリック使わないので
ダブルクリックなしのUIに慣れてきている自分 Windows7などでタスクバー上の自身のアプリにマウスを置いたときに表示される
サムネイルを別の画像にしたいのですが、やり方やサンプルなどはありませんか? エディットコントロールに値を手入力した後、フォーカスを失った時点で飛んでくるメッセージはありませんか?
エディットコントロールの値を、作業する直前に取り込む、という方法では、いろいろと不都合が出てきました。(たとえばレジストリへのバックアップなど) >>28
ありがとうございます。
強制的に、フォームに配置しているすべてのエディットコントロールへのフォーカスを失わせる方法はありますか?
関係ないコントロールにフォーカスを移す方法でもいいです フォーカスのあるコントロールにWM_KILLFOCUSを送信。 SendMessage(GetFocus(), WM_KILLFOCUS, 0, 0); SetWindowHookExのグローバルフックってもう使えないのかな?
64bitと32bitのアプリケーションが混合してる世の中だけど >>33
64bitのアプリケーションに32bitDllをマッピングしたら当然エラーが起きてプログラムが死んだんだけど・・・
マッピングするDllを切り替える方法とかが有るのですか? >>28
このたびはありがとうございました。無事に実装を完了させました。 最初から64bitDLLをマッピングすりゃいいんじゃないの? If a 64-bit application installs a global hook on 64-bit Windows, the 64-bit hook is injected into each 64-bit process, while all 32-bit processes use a callback to the hooking application. ウィンドウメッセージを監視するVisualStudioの付属ソフト Spy++ でさえ32bitアプリ監視向けと64bitアプリ監視向けで別々に必要なのだからしょうがない。 32と64のexeからそれぞれhookをするしかないよ。
SetWinEventHookとかで代用できるなら片方のみでもいける。 Windows10上で 64ビット開発してListViewを使う
レポート形式で列を複数作り、カラムの幅の総和がリストビューの幅を超えるようにする。
項目をマウス左右(どちらでも)ドラッグで複数選択しようとすると、列の末尾にスクロールが発生し、
このときマウスカーソルがディスプレイの右下や右上に吹っ飛ぶ。
win32(x86)では発生しない。
専用テストプログラム組んで発生したのでこの場合コントロールのバグ確定でいいかな。
古めのSDK(2008とか)使っているので、最新の開発環境で作っている人の発生状況を知りたい。 追加条件
ビジュアルスタイルを適用で発生・・・代替案不明 >>41
対処法は俺も知らんけど
FCU入れるとコモンコントロールのListView使ってるアプリは全部同じ挙動になるから
OS側の不具合で間違いないと思うよ ご相談させてください。
SetDIBitsToDevice 関数を使用して、bmp を表示させてようとしています。
ここで、メモリから bmp の一行分を読み込んで、SetDIBitsDevice() にて一行分だけ表示し、
繰り返し読み込みと表示を行数分だけおこなって表示させる方法を(特に)探しています。
https://ideone.com/v0METS
にて試行していますが、画面が真っ黒になりうまくありません。
どこが悪いのでしょうか?また、SetDIBitsToDevice() の第6〜第9パラメータ
int XSrc, // 転送元長方形の左下隅の x 座標
int YSrc, // 転送元長方形の左下隅の y 座標
UINT uStartScan, // 配列内の最初の走査行
UINT cScanLines, // 走査行の数
についてヒントをいただけないでしょうか?
よろしくお願いいたします。 >>49
「猫Winプログラム」を並行して修正しながらやっています。
というか、猫Winプログラムに乗り換えようか… バグだらけのひどいコードだな!
>>47よ!動かないの当たり前だ!
まず、グローバル変数で、HANDLE hFileを共有する設計前提で作ってるの?
51行目からのint WINAPI WinMain内でのバグっぽいの発見!
55行目:HANDLE hFile;
ローカル変数で定義だと…?
ローカル変数で定義するなら、そのコード内でhFileをCloseHandle();なぜしていないの?
hFileをグローバル変数で使いまわすなら、55行目のHANDLE hFile;のローカル変数の定義は不要じゃねーの?
まずは、55行目を削除しろ!
グローバル変数と、ローカル変数をちゃんと理解して使いましょう!
9行目からの LRESULT CALLBACK WndProc内でのバグ
14行目:int WIDTH = 0;
アプリケーションが終了するまで、イベントごとに毎回ウインドメッセージを処理する意味で、このプロシージャー呼ばれることは理解してるよな?
仮に、ローカル変数を確保はいいとして、case WM_PAINTでWIDTHは常に0なんだけど?
24行目〜のWM_CREATE内で一度だけ初期化して値をずっと保ちたいなら14行目は、static int WIDTH=0;じゃねーの?
そもそもCALLBACK WndProcの仕組み理解してる?
24行目
WIDTH = 4 * ((bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biBitCount) + 31 / 32);
はぁ…なんで意味不明な計算してるの?
WIDTH = 4 * ((bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biBitCount + 31)/ 32);
こっちが正しいんじゃね?これどういう意図で計算しているかわかってる?
猫のページ見てるならまずは、動くコードをコピペして動かせよ!手打ちでバグ作ってどーする!
コード見てて、ローカル変数の使い方や、ウィンドウプロシージャの仕組みがちゃんと理解できていないように見えるので、
直ちに、ウィンドウプロシージャでググってコールバック関数とはなにかを理解することを勧める。
猫のページの7〜10ざっくりみたけどウインドメッセージとウィンドウプロシージャの詳しい説明してないので別のとこ探して読んだほうがいいぞ。 俺からも追加
SetFilePointer は ReadFile の前にしないと
2度目以降の WM_PAINT で1ライン目がおかしくなる
最近のWindowsだと「2度目以降の〜」自体そんなに来ないかもしれんが >>51
ありがとうございます。
・hFile はこの関数(WinMain) だけで使う変数で、ここで一気にビットマップを読み込むのに使っています。確かに CloseHandle(hFilt) とした方がいいですね。
・int WIDTH = 0 はひどい、static int WIDTH にするべきでした。
・WIDTH = 4 * ((bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biBitCount) + 31 / 32); これもひどいなあ…ご指摘されてはじめてまずさがわかりました。
ようはビットマップの一行の幅を 32ビット単位にする操作ですね。31をたして、全体を 32 で割って DWORD 数を出し、それに 4 をかけてバイト数を出す、
ご指摘のとおり
WIDTH = 4 * ((bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biBitCount + 31)/ 32); にいたしました。
すると画面に縦じまが現れました。これは重大な進歩です、これを元にもう一度元ソースを見直します。
ありがとうございました。 >>51
>>53
すみません、hFile はグローバル変数でした。ローカル変数定義を削除しました >>51>>53
ご指摘を受けたあたりを修正して、うまく表示できるようになりました。
コメントをいただき、ありがとうございました!
https://ideone.com/W8wuOF
>>52
SetFilePointer() は次回 WM_PAINT 時に備えたものだと考えています。 >>46
解決したみたいだけど、デバッグの知識は身につけといた方がいいよ。
無駄な試行錯誤をする事が減って使える時間が増える。 線だけで長方形を描画したいのですが、もっとも簡単に実現できるAPIはどれですか?
cで使えるものでお願いします win32APIのみなら>>59 >>60のを使うといいよ
速度重視で2d描画をしたいなら、Direct2dのAPI使ったらどうだ?線を描くならDrawLine、長方形ならDrawRectangleで描けるぞ。 jpg や png などの2D静止画を高速描画するのに最も適したライブラリってどれだろう?
gdiplus? DirectX? ハードウェア描画前提ならdirectXじゃないかなー
wikiでgdiを調べると詳しく書いてあるかもよ。
好きなライブラリー使えばいいよ。 最終的にはメモリDCに書き込んだのをBitBlt()するのが組みやすい
フォーマット変換だけならwicやOpenCV メモリDCで作業してるのに、スレッド排他ロックでアプリ側のマルチスレッド実装を台無しにしてくれるgdiplus jpgだとJpegTurboってのがあって、それなりに速かった
jpgで画像を連続で送ってくるカメラがあって、それで試しに使ったことがある >>62
表示だけならライブラリ探さなくてもOleLoadPicture()で読み込んでDCにIPicture::Renderするだけでいいんじゃないか? メモリDCへの拡大縮小画像のレンダリングを高速に実現する最適な方法ってなんなのだろう?
ちなみにGDI+ gdiplusは論外。GraphicクラスでメモリDC渡してレンダリングすると、GDI+がスレッドロックするので並列化による省時間はできない。 最適ならDirectX一択だろ
最速になると描画よりも拡大縮小アルゴリズムの話になりそう >>67 の方が教えてくれた IPicture::Render はWindows2000時代からあるレンダリングAPIという認識。
わざわざVista時代にDirect2dをリリースした意味は何なのか、という疑問がありまして、その辺どうなの、と。 32bitARGB画像ならDirect2Dだな、小数点座標指定できるし。
Direct2DのAPIではピクセルフォーマット変換とかHeight方向反転とかできなかったと思うので
異なる場合には渡す前に変換しておく必要がある せめて有名Webブラウザ並みの描画速度で複数画像を一覧表示できてほしいんだけど、その点、gdiplusはダメダメ。
Wikipediaなどの情報によると有名WebブラウザはDirect2Dによる描画らしいので、Direct2Dがいいのかな。 今作ってるソフトの遅い部分が「描画」でそこを改善したいんじゃなくて、たぶんこれから作るソフトの計画だよな
ある程度形になってからどこに時間食ってるか調べてそこを潰したほうが開発時間も動作速度もいいと思うな >Direct2DのAPIではピクセルフォーマット変換とかHeight方向反転とかできなかったと思うので
当然SetTransformはあるしなんなら自分で書いたシェーダを挿入できるエフェクトグラフもあるでよ? >>76
SetTransformで鏡像反転できるのか
マトリクス係数考えてみるわ 低レベルな話ですみません。
ダイアログアプリケーション(calc.exe と同様)
を win32api/C で書いています。
希望:ベースのダイアログの色を起動後に変えたい。
したこと: WM_CTLCOLORSTATICを捕らえて、
SetBkColor((HDC)wp, BackGroundColorG); および
return HBRUSH / HBRUSH を DefWindowProc() に渡さずに返す
以上で、スタティックコントロールの背景色およびエディットコントロールのディスエイブル時の背景色は変わりました。
しかし、ベースダイアログの色は変わりません。
頭で、RegisterClass() にわたす前に設定する WNDCLASS の hbrBackground の値が、ダイアログのCreateWindow() の後も反映されています。
後から
SetClassLongPtr((HWND)lp, GCL_HBRBACKGROUND, (LONG)hbrBackGroundS)
しても反映されないことを確認しています。
起動後にダイアログの色を変えるにはどうすればいいでしょうか?
明日には再現コードをお見せできると思います。
アドバイスいただきたくよろしくお願いいたします。
#WINDCLASS.hbrBackground = NULL にすると、透けてデスクトップが移りこみ、これはこれで面白いです…もう寝ます >>80
WM_CTLCOLORDLG でブラシを返す >>81
コメントいただき感謝しています。
試してみたのですが、よくありません。やはりダイアログは WNDCLASS.hbrBackground の指定が優先されています。
現象を再現させたコード次のとおりです。こちらでは cygwin/mingw 32 ビットでコンパイルしています。
test.c https://ideone.com/pch378
test.h https://ideone.com/1iKq2z
test.rc https://ideone.com/kZH3Uf
makefile https://ideone.com/9MDXT0 >>81, >>83-84
コメントありがとうございます。
状況が変わりました。すなわち、
1. DefWindowProc() ではなく、DefDialogProc() にする
2. (>>81) WM_CTLCOLORDLG メッセージ処理(ブラシを返す)
によりダイアログのベースの色が変わりました。
現在典拠を探しています。
遅いところ皆様ありがとうございました。勇気がでてきました!
https://ideone.com/ZBuhbz
>>84
StackOverflow のプログラム例は、(通常)ウィンドウがあって、そこから CreateDialog で新しくモードレスダイアログを作るときの作法ですね。
IsDailogMessage() が必要かどうかは、まだよくわかりません。 大雑把に言うと WindowProc に来る前 DefDlgProc が
値を返しちゃうので色が変わらないわけです (多分)。
他にも DefDlgProc が反応するメッセージについては WindowProc ではなく DlgProc で処理する必要があります。
どれがそうか一覧等あるのかは知りませんが。 フルスクリーンでも、色の取得ができるAPIは存在しないのでしょうか?
GetPixelを試みましたが、何故かフルスクリーン対象にすると 常に0を返されます
フルスク色取得が可能なapi、もしくはGetPixelでも出来るのでしたらやり方を教えてください 質問です。
あるソフトがしたUSBの出力を、コンピュータの外部ではなくそのコンピュータ内の他のソフトへリダイレクトすることはできますでしょうか? >>90
方法1 (「あるソフト」にパッチが可能なら)
CreateFile()/WriteFile()などをフックする。
ただし、これらはKernel32.dllにあるAPIなので通常の方法ではフックできない。
「あるソフト」内のByte列"Kernel32.dll"を(例えば)"Xernel32.dll"に書き換え、
Xernel32.dllを作成・フックする。
方法2
対象デバイス用デバイスドライバと同じAPIを持ち、かつその入出力を「他のソフト」
へ受け渡すAPIを持つデバイスドライバを作成する。
方法3 (本物のUSBデバイスも生かしておくなら)
フィルタードライバーを作成し、そこで「あるソフト」の出力を盗み見る。 kernelにあっても普通にインジェクトでフックできるような・・・ と、書き込んでからプロキシ思い出した。あれ64bitのは作るの面倒すぎだけど32だったらありだな USBハブで物理的にteeすることって可能なんだろうか Window API Hook で検索すればすぐ出てくるけど API のフックはかなり簡単にできる
DLL インジェクション併用で CreateFile / WriteFile をフックするのがいいかもね > ・APIフックなど高度な事をしたい場合はできるだけAdvenced Windowsを読みましょう。
テンプレのこれいるか?ってほど簡単にできるしな
1つのページを見るだけではできなくても
いくつかのページの情報を自分なりにまとめたらできるようになる 皆さまありがとうございました
APIフックを試します うーむ、やっとコンパイルできた…
32ビットコードは 32ビットのODBCデータソースしかみないし
64ビットコードは 64ビットのODBCデータソースしかみないのか…
手持ちの excel は 32ビットで、見に行くODBC テーブルは 32 ビット用であったことが混迷に拍車をかけてしまっていた
cigwin の odbcライブラリとしては -lodbc32 でコンパイルしているが、32ビットなのか 64 ビットなのか、いったいどうなっているんだ?! shell32.dll とか kernel32.dll とかもそうだし、
32→64 ビットではモジュールの名前変わらなかったからね ■ このスレッドは過去ログ倉庫に格納されています