Win32API質問箱 Build126
レス数が1000を超えています。これ以上書き込みはできません。
Win32APIについての質問はこちらへどうぞ。
■注意
・質問する前にMSDNライブラリやPlatformSDK、Google等で検索しましょう。
・日本語版MSDN Online Libraryは不完全です。
英語版( http://msdn.microsoft.com/en-us/library/ )の利用推奨。
・APIフックなど高度な事をしたい場合はできるだけAdvenced Windowsを読みましょう。
・言語特有の問題やIDE、MFCやVCLなどの質問はそれぞれの言語や開発環境スレで
■過去スレ
Win32API質問箱 Build125
https://mevius.5ch.net/test/read.cgi/tech/1551247748/
Win32API質問箱 Build124
https://mevius.5ch.net/test/read.cgi/tech/1510395780/
■関連スレ
Visual Studio 2019 Part4 https://mevius.5ch.net/test/read.cgi/tech/1585715794/
Visual Studio 2017 Part7 https://mevius.5ch.net/test/read.cgi/tech/1558179898/
【C++】 DirectX初心者質問スレ Part41 【C】 https://mevius.5ch.net/test/read.cgi/tech/1521786252/ MemoryMappedFile で造ったファイルのパスとかファイル名を取得する方法はありますか? 991 蟻人間 ◆T6xkBnTXz7B0 sage ▼ 2020/04/07(火) 19:03:16.48 ID:qBIbpTMr [1回目]
https://archive.org/details/NTDocumentation/mode/2up
992 デフォルトの名無しさん ▼ 2020/04/07(火) 19:09:20.97 ID:G5F9VLMp [1回目]
>>991
下部の他のリンクが色々あるね MoveFileって同一ドライブであればディレクトリも移動できたんだな
エクスプローラーだと一瞬だし何かおかしいと思ってたが
今まで再帰で糞真面目に移動してた
>Windows NT/2000:この関数の ANSI 版では、名前は最大 MAX_PATH 文字に制限されている。
>この制限をほぼ 32,000 ワイド文字へ拡張するには、この関数の Unicode 版を呼び出し、パスの前に "\\?\" という接頭辞を追加する。
これも知らなかった
ファイラーとか作ってる人ってこの辺ちゃんと処理してる? MoveFileって同一ドライブであればディレクトリも移動できたんだな
エクスプローラーだと一瞬だし何かおかしいと思ってたが
今まで再帰で糞真面目に移動してた
>Windows NT/2000:この関数の ANSI 版では、名前は最大 MAX_PATH 文字に制限されている。
>この制限をほぼ 32,000 ワイド文字へ拡張するには、この関数の Unicode 版を呼び出し、パスの前に "\\?\" という接頭辞を追加する。
これも知らなかった
ファイラーとか作ってる人ってこの辺ちゃんと処理してる? はい
ttps://m.facebook.com/dnobori/posts/2142836202459674 GetQueueStatus() API って Windows10(もしかすると 8)以降
動作が遅くなってない?
(未だに VB6 で作成したソフトをメンテナンスしている関係で調べてたら、
DoEvents より遅くなっていることに気が付きました) >>14
それとも、64bit OS だからでしょうか?
(Windows10 の方は 64bit です) 連投すみません。
64bit OS だから遅くなるということはないですよね・・・
g++ で簡単な速度計測用のプログラムを使って確認してみました所、
Windows7 と Windows10 では、約 6 倍くらい速度差がありました。
(まさか、Windows10 で遅いのは、Windows Defender が原因だったりして・・・) まさかWindows10のデフォルトの電源モードが省電力になってるのを知らないとか 基本的なことかもしれませんが、教えてもらいたいことがあります。
Win32APIで作成中のゲームで、ウィンドウを最小化してみてタスクバー格納してみたら、
画像の背景部分の画像が消えて、背景が真っ白になってしまいました。
もとのプログラムでは、背景画像の描画時に
InvalidateRect(hWnd, NULL, FALSE);
と第3引数FALSEで背景画像を残しているつもりなのですが、
どうやら再描画の際に、TRUEで再描画してしまっているので白い背景に置き換わるのかと(予想ですので、正しい保証はありません)。
最小化しても、画像を保存する方法を教えてください。
タスクバーに格納中の状態にマウスを合わせて内部表示させてみたところ、
格納中のときは背景を表示できてるようです。
タスクバーから出した時に、背景が消えてしまいます。
なお、画面のチラツキを防ぐために背景描画時にオフスクリーン(裏画面)をしています。 自分のプログラムじゃなくてOSからの再描画要求でWM_ERASEBKGNDも走って
ウィンドウクラスのブラシでクリア(既定の動作)されてるパターンじゃねえのん >>20
とりあえず
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
(以下略)
ってコード追加して試してみたけど、改善しなかったです。
ウィンドウクラスをどう変更すればいいか、ワカラナイです。 InvalidateRectに関係なく、描画が必要な際にWM_PAINTが送られてくる。
BeginPaintで描画が必要な領域を調べてその後自分で描画する必要がある。
InvalidateRectは再描画したい部分を指定するために存在し、第3パラは
単純にその際に消去するかどうかを指すのみ。
今回のはタスクバーから出したときにOSが再描画しろと仰ってWM_PAINTを発行してるから従いなさい。 ここ数年触ってなかったけどなーんかWM_ERASEBKGNDの挙動が変わってるような気がするなあ
こんな役に立たなかったっけ・・・?
>>18
とりあえずWNDCLASSのhbrBackgroundを0にすればOSによる背景消去は無視されると思うけどどうよ? >>18
それは最小化したときのWin32の昔からの挙動。
InvalidateRect() の bErase や WM_ERASEBKGND は、今残っている画像を
消すか消さないかを制御することはできるが、
ただそれだけのことで、消す以前に現実に画像が画面上に残っていない場合は、
消えたままとなる。
Windowsは、Aeroなどより前の時代、各Windowは原則的に仮想VRAMを持たずに
自分で実VRAMに描画する方針だったので、最小化して戻したときは、
自分で再描画しない限りは、デスクトップの画像か、背景色で真っ白に消された
状態で復帰するだけだった。
Aero以後は、仮想VRAMを持つモードがあるとされる。 NGワードのテスト
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); NGワードで、結果が書き込めない。
投稿文の何がマズイかワカラン。 とりあえず、
wcex.hbrBackground = 0;// (HBRUSH)(COLOR_WINDOW + 1);
と変えてみました。
ですが結果はタスク バーから出した際に再描画されてしまいます。
ですが、背景の色が黒に変わりました。(以前は背景が白で再描画でした。)
たまたま自作ゲームでは背景色が黒でしたので、これはこれで好都合かもです。 >>25のコードがあったので、>>27のコードに変えてみた。
結果はダメだったです。 NG ワードは、MANGO 板のスレで、絞り込みができる
cmd@.exe
ls の特定のオプションとか
はてなブログのURL で、吸い込まれるような動きをしたら、絶対に続けて書き込んではいけない。
3日ぐらいアクセス禁止にされる
twitter の長いURL も、吸い込まれるものがあるとか >>22
>今回のはタスクバーから出したときにOSが再描画しろと仰ってWM_PAINTを発行してるから従いなさい。
ご指示の通りにして、とりあえず解決しました。
Windowsの場合、OSが割り込んで、むりやり画面クリアして再描画してしまう場合があることも意識して、
画像の描画プログラムを組み立てる必要もあるのですね。
処理を軽くしようとして、背景は1度書いたら背景フラグをオンにして再描画しないようにしてたのですが、
OS割り込みによる再描画を考慮してなかったので、
裏目に出てしまったようです。 >>30
OS割り込みというか、WM_SIZE メッセージが来たら、背景も何もかも
全部再描画するようにすれば良いだけ。 >>32
なお、WM_SIZE が来ても、その場で本当に再描画するという意味ではない。
WM_PAINT つまり、MFC でいうなら、OnDraw() 関数の中で背景も何もかも
再描画されるように工夫する。
そのためには、何らかのフラグを用意して、普段は0にしておき、WM_SIZE
メッセージハンドラであるOnSize()の中で 1 にする。
OnDraw()関数の最後で0にする。 >>31
描き込んでもレスに反映されないことがある
可笑しいと思ってもう一度そのまま同じ内容を描き込むと
そのままアク禁 大きさ固定で BMP に描画
WM_PAINT は BMP を BitBlt するだけ
大きさが変わったとき 自分の意思で表示内容を更新する時は BMP をゼロから描画しなおす
WM_SIZINGで大きさが変わったを知って
見合ったサイズのBMPに作り直し→表示内容を更新 VBAでAPI使ってるレベルの者だが、メモリDCからBitbltするだけじゃね? とにかく、最小化状態から通常状態に戻したときは、何もかもそれまでの描画が
失われるのは昔からのWindowsの仕様。
普段は高速化のため部分描画をしたい場合は、そうしておいて、WM_SIZEが
来た直後にだけは、なんとか色々な方法で工夫して全体描画すればよい。 CreateWindow関数って存在しないの知ってる?これ豆な >>38
マクロでは存在している。
実際のDLL内での関数名は、Unicode版と非Unicode版でそれぞれ語尾にWとAが付くが。 >>39
CreateWindow
って、ファイルシステムとは関係ないのに、どうして A と W を実装しているのでしょうか? >>40
結論的には、クラス名、Window名が CHARかWCHARかの違い。
今見てみたら、
1. CreateWindowA、CreateWindowWも、それぞれ、
CreateWindowExA、CreateWindowExW に置き変わるマクロである。
2. CreateWindowは、UNICODE マクロが定義されていれば、
CreateWindowW を通じて、CreateWindowExW に置き換わる。
定義されていなければ、
CreateWindowA を通じて、CreateWindowExA に置き換わる。
3. A 系は、クラス名、Window名が、CHARへのポインタであるのに対し、
W 系は、クラス名、Window名が、WHARへのポインタである。
4. CreateWindow() や、CreateWindowEx() は、クラス名、Window名が、
どちらも、TCHARへのポインタであるので、UNICODEマクロが定義されている
かどうかで、それらの文字列がCHARかWCHARに自動的に切り替わる。 〜Exって関数名、拡張は1回きりって浅はかな付け方を
よくここまで堂々とやるなって感心しちまう バージョン増えると後ろに2とか番号付くぐらい適当だよ なんなら***ExExもアリだからな
Exが一度だけという浅はかな固定観念に縛られていてはMSには成れないのさ GetTextExtentPoint32にもっとEx付けたい じゃあ逆にどうしろと?
eclipse のソースコードなんかでも、インターフェースはバージョン番号増やしてく感じだよ
IDocumentExtension
IDocumentExtension2
IDocumentExtension3
IDocumentExtension4 IDocumentExtension98
IDocumentExtension98SE
IDocumentExtensionMe
IDocumentExtension2000
IDocumentExtensionXP IDocumentExtension7
IDocumentExtension8.1
IDocumentExtension10
IDocumentExtension2000
あれ?2000が一番新しいんかな? IDocumentExtension8.1って、ここだけメンバーなの? CreateWindowは元々これが実体
win98辺りでunicode対応となってから内部でAとWに分けられてって流れじゃなかったっけ
歴史長いんだからよっぽどの先見の明がないと名前の整合性なんて無理でしょ
内部の関数ならまだしも外部公開のAPIなんてね
名前や仕様がころころ変わって阿鼻叫喚になるよりマシ Aって ASCII の A ?
W は、 Wide の W ?
でいいんけ? >>50
win16(win3.1)では実態
win32(NT,95)でAとWに分割。マクロで互換性をキープ
ただし9xは殆どのW系を実装しておらず失敗する
win32cとか呼ばれてた 文字コードの ANSI って、なんなんだろ
ASCII とか Shift-JIS とかだと分かるけど、
ANSI って言われると、…ん? ANSI …?ってなる
メモ帳の ANSI って、Shift-JIS のことなんだっけ?
なんで Shift-JIS をこんなわけわからん名前にしてるんだろ ウィンドウズのマルチバイト文字列変換は、コードページ切り替えで実現している。
既定のコードページANSI (CP_ACP)は、日本語ウィンドウズでは932(Shift_JIS)に転送される。英語圏のウィンドウズでは1252などになる。具体的な値はGetACP関数で取得できる。
シフトJIS変換では、WideCharToMultiByteとMultiByteToWideCharの第一引数にCP_ACPではなく、明示的に932を指定した方がいい。 ANSI・・・ JISと敵対する組織であり世界に暗躍するISO一味の筆頭
Shift-JIS・・・ 悪の秘密結社MSにより改造されたJIS >>54
CreateWindowは2000からAとWだね
95〜98系はほぼUNICODE対応されておらず、リソースや文字列を扱うごく一部のしかない
>>55
ANSIがASCIIを制定
これをベースに各種ローカル文字コードが乱立
そしてUNICODEへ いい加減Aはサポートを打ち切っちゃえと思う
TCHARの為に無駄な手間が増える 無理にTCHAR使わなくて良いんだよ
_Tも_Lも面倒なだけ 自分でA環境切ってれば面倒は無いと思うが
AのAPI残してるからこそ生き延びてるレガシーアプリはまだ無視できねんじゃないかなあ
未だに日本語パスとかでコケるアプリがあるのはそのせいでもあるんだろうけど >>60
無理ではないけど...
Aを切ってくれないと思い切りが
そういえば
Wしか使えないWindowsが昔あったな レガシーな制御機器を扱うソフトからすると、OSでUNICODEに一本化されると困るというか面倒極まりない APIのA系がいらんというだけで
制御系は好きな文字コードでやれば良いんだよ
ファイルのアクセスや各種プロトコルでは
いろんな文字コードを使うはずで
全ての文字コード用に各種APIが対応してる
なんて必要は全く無い
変換APIだけ用意してくれれば良い OS側で文字を入力・加工したものを制御系に流す、又はその逆のことを全く考慮しないならそうだね でもUTF8って、マルチバイト文字じゃないの?
W系の関数ってUTF16だよね? UTF8とUTF16は表現が違うだけで空間は一緒やろ
(厳密には一対一ではない)
Shift_JIS と UTF16 とかで変換しようとすると化けたり欠けたりする
WideCharToMultiByte と MultiByteToWideChar の引数は UTF8 だけにするべき 要求されているコード次第だろ。
SJISが必要な場面で変換できない文字が含まれていたならエラーにするだけ。 Go は、ワイド・UTF-8。
Windows は、ANSI・CP932
だから、Windows のみ、変換が必要!
WSL なら、Linux/Windows間の変換を、Windowsが自動変換するだろ ちょっと前にWindows10がUTF8を使用する機能が追加されたと聞いたけど、あれはどういう仕組みなの?
開発するときはWCHARやW系の関数を使っててもいいの? >>73
>Windows10がUTF8を使用する機能が追加された
設定で A 系がデフォで UTF-8 になると聞いています >>74
ということは、A系はなくすどころか、これから主流に戻っていくということ? 設定で変えないとな今だとちゃんとシステムがUTF8かどうか確認しないとバグるだろうなぁ。。。 A系やWideCharToMultiByteを使ってかつsjisだと決め打ちしてるとバグるね 聞いてるだけでよくわからなくなってくる
マルチバイト星人はこの先もしばらくは無駄な苦労をしていくことになりそう >>80
mingw で提供されている <windows.h> は TCHAR を使っているから、おさらばするわけにはいかないでしょうね…
https://mevius.5ch.net/test/read.cgi/tech/1434079972/53 マイクロソフトが提供為てるわけじゃないんだし知ったことかよ 創造主は世界を A と W に分けた。
後の A&W である。 >>70
> (厳密には一対一ではない)
UTF8 と UTF16 って符号化文字集合は同じだから全符号化表現が一対一対応するんだと思ってたわ
例えば何が一対一にならないん? WinSockの話はこのスレであってる?
ブラウザを作りたいんだけど、書店で本を探しても無くってさ プロトコルはRFCをあたる
受け取ったデータの可視化やうそんこの文字指定から文字化け回避とか、そっちのほうは知らない >>86
自作ゲームに、将来的に通信対戦の機能とかをつけたいから。 >>87
わかった。RFCを調べてみる。
あと、2ちゃんの別スレも見つかったから、それも調べてみる。
『ネットワークプログラミング相談室 Port30 [転載禁止]©2ch.net 』
https://mevius.5ch.net/test/read.cgi/tech/1414709836/ 32bitOSが終わるだけでWOW64は無くならんと思うが 過去資産切り捨てるだけでメリット皆無
ってこの話題何回目だ >>94
ということは16bitアプリ終了のお知らせってことか >>97
コスト削減どころかWindowsシェア削減になるね 「どころか」
全然つながってない
32bitのシェアが減ればコストに見合わなくなるので
開発を打ち切るのは当然
それによってアプリ開発者も負担が減る
OSの64bit化で16bitを切ったのもそういう理由 素人たちはこれだから困る
32ビット対応を継続することで、比較対象ができることでバグが少なくなるのだ
両方で動くコードは安定しているし、今後128ビット対応にも生きてくる 同じコストを書ければ
片方だけの開発、評価の方がバグが少ない
当然だ 128bit?
そんな時代は少なくとも数十年は来ない sizeof int == sizeof long
よりも
sizeof int < sizeof long
の方がなじみがある int : 16bit / long : 32bit
int : 32bit / long : 32bit
int : 32bit / long : 64bit
どれも良く使う
Windowsに限定すれば今は32bit/32bitだけだが 趣味のプログラムだと32bitアプリはもう作らない
仕事だとまだ必要 まーた自分の希望的観測を大局的指針だと強弁しちゃう勘違い君が来ちゃったか
前と全く同じ事言っちゃってて進歩してないな なんのこっちゃと思ったらOEM向けの32bit版OSを提供しなくなるってだけの話か
Windowsに関しちゃMSはゆーっくり削ってくねえ この人前も同じ様なガバガバ理論を連レスしてたな
> 16bitは切った
> これが事実
これをドヤ顔で推すのなら、同じ理論で128bitOSが出るまでは32bitアプリは生きることになるぞ >>116
なんで?
AMD64は16bit切ったけど、128の時32bit切るってどうして言い切れるの? 16bitは切った
32bitもいずれ切る
128bit CPUは出ない 32bitのCPUが4つだから128bitだ、と嘘をつくゲーム機メーカーがあったな インテルのロードマップによると次に出るのは80ビットプロセッサ。 レジスタに名前つけてほしいんだ
r10とか無機質な使い捨て兵士みたいな奴よりraxやrbpのほうがかわいげがあるだろ >>122
Cellに関してそんなデマ流れてたっけ? >>124
鉄オタを見てみなよ
103とか485とか、謎の数字で大喜びしてるよ? 昔、昔、あるところでの対話
友人: おまえPC何使ってんの?
俺: 486/33
友人: ???????? PCを問われてるのにCPUを答えたらそうなるだろ
車何のってんの?って聞かれてHR15DEとか言ったら
オタクを蔑む目で見られるだけだろ >>124
なんだ…トムとかマイケルとかじゃないのか… >>130
MichaelはMikeでもMikeyでもMickyでもMickでもいいとかになるのかな >>125
CELLのSPEは128bitレジスタを128基備えた本物で、32x4のSIMD演算ができた。 今のPC用CPUは256bitレジスタがあって
64bit x 4 のSIMD演算が出来るから
256bit CPUか 昔のベクトルコンピューターは
65536bit CPUとか? >>133
8bitCPUと言われる奴にだって16bitレジスタはあったよ?
でもそれを16bitCPUとかいったら馬鹿にされるよ? 〇〇bit CPUネタはいつも定義がグダグダで荒れる元 >>138
昔から定義があいまいだしな
30年以上前はデータバス長で決めるのが主流だったと思う
なので68000は16ビットCPUと言われることが多かった
でも、68000は内部が32ビットだからと32ビットCPU扱いしてる本もあった
子供ながらに早く定義を確定させろよと思ってたな >>144
8085 は Z80 に似た位置付け
8088 は 8086 の 8 bit 版 8080 は周辺回路用に、8251 (USART)、8253 (CTC / PIT)、8255(PPI)
というファミリがあったんだ。
「CHIPSET」というものの走りか。 ALUで一度に計算できるレジスタ長でいいんじゃないかね Project REUNION
このスレもまだまだ終わらんね アドレス空間の広さという定義もあった
さらに仮想アドレスや実アドレスに物理的サイズ(アドレス線の数)とか Win32でなんでこの話かとは思うが、基本的に
どれでも頭打ってる最小のビットがNならNビットCPUだろ
アドレスバスが32ビットでも命令長が16ビットのしかできなければそれは16ビットCPUだ >>153
その定義だと64bit CPUがほとんど無くなるけど
良いのかな? >>154
32ビット命令「しか」できないCPUそこらにないだろ
AMD64も「全部」64ビットだ Win32的にはexeヘッダのmagic#が10Bか20Bかだろ Win32のカオスもたいがいだが、それを置き換えきれないドットネットもダメすぎる 何かしら新しいものを担ぎ上げたと思ったら梯外しを続けて屍累々だしね
泥林檎全盛時代モバイルWin大敗北という状況なのに、それでもUWPでバリバリ開発するぞってプログラマーなんて増えないだろ?と思ってたけど、この有様よ
>>158
我々の勝利でしょう EnumWindowsのコールバックの中でHWNDからEXEを割だそうとしてるんだけど
GWLP_HINSTANCEで取得したハンドルをGetModuleFileNameに渡してもうまくいかん
どうやんのコレ? 全然関係ないけど、この略であってる?
なんか Win32API って、略しまくってて一見さんお断りって感じ
GWLP
Get Window Long Pointer
HINSTANCE
Handle to the Instance この略で書かれたオプションを使ってる関数名の略語なんだから別にこれは合理的だろ
GetWindowLongPtrAのオプションなのにEDH64_とかで始まってたら頭おかしいが >>166
昔はエラー情報へのハンドル値だったとどこかで読んだ気が エラー情報ハンドルからエラー情報を取得するには関数を使います >>169 >>170
なるほどね。
海外のサイトで、「Hex Result」説を書いていた人がいたが、どっちが正しいの? >>173
it really was a handle to an object that contained rich error information.
これが答えってことかい? HFONT,HBRUSH,HDC,HPEN,etc
何でもかんでもハンドルとして扱ってるのに、HRESULTだけHEXかもなんて思うの? >>175
HEXと思うのはどうかと思うけど
> HFONT,HBRUSH,HDC,HPEN,etc
こいつらはハンドルだけどHRESULTの型はlongだし値もどう見てもハンドルじゃないからあーだこーだ言ってるんだろ 通常voidだがエラーの場合は符号付きのlongにしてるだけ
実質型を隠蔽してハンドルとして扱うのは慣例みたいなもんだし、気にする必要は無い >>174
要は昔の仕組みが型名として残ってるだけだと >>174
それは昔の話、今は
The COM team decided that the cost/benefit simply wasn’t worth it, so the HRESULT turned into a simple number.
But the name stuck.
ってことだろ >>177
お前は何を言ってるんだよw
HRESULT型のハンドル返すAPIなんてないぞ >>173
だから意味不明な "interface not supported" とか返ってくるのか
Cだとエラー情報の領域管理が面倒なのはわかるけど固定で5個ぐらい持つとかやりようはあったと思うんだけどね >>176
bool なのに 0 と 1 と -1 とか帰ってくる API に何求めてんだ >>183
boolとBOOLをいっしょにすんなよ https://ideone.com/iTPLPg
これなんで動かないんですか?
フォーマットノットサポートって出るんだけど、意味が解らないです。 メイン関数です。
#include <iostream>
#include "WaveDeviceII.h"
int main() {
WaveDeviceII WD;
WD.Initialize(WAVE_MAPPER, NULL, CALLBACK_NULL , 8, 2, 8000);
} The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats.
エラーです。 ここ Win32 API の質問箱なんですが、
WaveDeviceII とやらがなんなのかをノーヒントで推測する能力が求められてます…?
…そもそもリンク先見てないけど 再生・録音デバイスの設定がおかしいか、ドライバの問題ではないかな WaveOutDeviceIIに名前変えなきゃ。。。
>>191
うーん。他のアプリで音が鳴らないわけじゃないのだけど。うーん。 >>187
具体的にエラーを出したAPIを特定して、その仕様をググって調べてこい。
あとその英語のメッセージに具体的に何をしろと欠いてあるからそれも調べて試してこい。 接続されているUSBメモリの名前ってどうすれば取得できますか?
ドライブレターではない名前で、メーカー名とかが含まれるやつです。
例:SONY、Transcend SetupDiEnumDeviceInfo でデバイス列挙してゴニョゴニョすればいいんでない? >>196-197
おおお!!ありがとうございましたぁ!! GDI+のスレッドがないのでここで質問させていただきます。。
SetStretchBltMode(COLORONCOLOR)の描画をGDI+のDrawImage()でやろうと思ったら、
どのような指定をすればよいのでしょうか。
なにも指定しないままだと補間がかかってしまうのですが。 答えになってないように見えるけど
メモリコンテクスト相手にGDIで SetStretchBlt かけて出来上がったものを
GDI+ のDrawImage()に渡せということかしら >>162
できた dx
QueryFullProcessImageNameっての見つけて使った USBカメラから静止画データ(ビットマップorPNG形式)を取得したいのですが、
やり方が分かる人がいたら教えて頂けないでしょうか。
言語はC/C++です。
DirectShowかMedia Foundationを使えば良いという所まで分かったのですが、
それから先に進めない状態です。 ご返信ありがとうございます。
>>207
OvenCVは商用で使いずらそうなので、APIを使いたいと思っています。
>>208
ざっとしか見てないのですが、
OpenCVを使ってキャプチャしてるので合ってますでしょうか。
OpenCVでは無くwindows APIを使ったサンプルがあったら助かります。 OpenCVはBSDライセンスだから商用でも使いやすい部類 ソースコードのライセンスとは別に特許が絡むのね
>>210は無視して Media Foundation でキャプチャするならまずMSDNのドキュメントを読む
https://docs.microsoft.com/ja-jp/windows/win32/medfound/audio-video-capture
個人のブログなど
http://codeit.blog.fc2.com/blog-entry-5.html
OpenCVのカメラ入力はお手軽だけどあくまでもOpenCVのおまけだしな。
フォーマットが選べなかったり複数カメラのどれが何番かわからなかったり。
VfWなんていまさら論外。 >>212
Video for Windowsも検討したのですが、
かなり古いAPIみたいでいつまでサポートされるか不安だったので
DirectShowかMedia Foundationでいこうと考えていました。 >>213
ありがとうございます。
調べてみます。 まぁ、やり方は色々あるよね
私だったらキャプチャするDirectShowのフィルターだけ作って
モニタ表示はフィルター構築できるプレーヤーに任せるかな >>213の
http://codeit.blog.fc2.com/blog-entry-5.html
のサンプルを実行してみたのですが、
フォーマットがVFT_YUY2と表示されました。
ビットマップ、PNG、JPEGなど、画像ファイル形式に出力フォーマットを変更したいのですが分かる方はいないでしょうか。
MSDNを見ているのですが、動画キャプチャのサンプルはあるけど静止画が見つかりません。
(visual studio2010ラインタイムを消さないとSDKがインストール出来なくて苦戦した。) そりゃカメラの出力フォーマットだな。ものによってはmpegやmjpegで出力できるカメラもあったりするが。
画像ファイルフォーマットの出力はWICとかを使うことになるだろうけど、そこへの並び替えはたぶん
自分でやるしかない。 directshowとsamplegrabberでいいんじゃないの
qedit.h書き換え必要だった気もするけど https://docs.microsoft.com/ja-jp/windows/win32/medfound/mfcaptured3d-sample
このサンプルをよく見たら、動画を吸い出しているのではなくて、
静止画を1フレームずつ、RGB32フォーマットに変換して画面に表示しているだけみたいでした。
RGB32フォーマットならとりあえず、保存・表示が出来そうなので、
このサンプルを使って静止画をキャプチャする方針で進めようと思います。
回答してくれた方々、ありがとうございました。 CreateWindowにてトップウィンドウ生成時、WitdhとHeightを指定し更に子コントロールもメインフォームと同じWidthを指定して作成したらトップウィンドウ側の方が横幅が小さくなってしまいます
少し小さいとかではなく10、20は小さく作成されてしまいますが何かオプションが必要なのでしょうか? >>224
トップウィンドウのスタイルと子コントロールのスタイルは何?
トップウィンドウのCreateWindowで指定するサイズはピクセル単位で外枠を含めたサイズ。
子コントロールの位置は、トップウィンドウの中のクライアント座標系で指定し、子コントロールのサイズはピクセル単位で子コントロールの外枠を含めたサイズ。
トップウィンドウでクライアント領域のサイズを指定したい場合はAdjustWindowRectEx関数を使用する。 スクリーン座標とクライアント座標を相互に変換したい場合はMapWindowPointsかMapWindowRectを使用する。 >>225
トップウィンドウはWS_OVERLAPPEDWINDOWで
子コントロールはコンボボックスでWS_CHILD | WS_VISIBLE | CBS_SORT | CBS_DROPDOWNLISTにしてあります
両者ともにWidthは200としていますが、明らかにトップウィンドウの方は200未満でおおよそ190あるかないかです
ちょっと調べてみたところWindows10だと左右7づつ縮むみたいな説もあるようですがそのせいなんでしょうか >>228
Widthなどは、同じ値じゃ駄目。
TopWindowの左右のBorderのドット数を引き算した値を、子ウィンドウの
Widthに指定する必要がある。
どのくらい引けばよいかは、>>225-227 で求める。 >>228
TopWindowのWidthは、枠を除いた部分のドット数ではなく、
枠まで含めたドット数。
だから、ChildWindowのWidthと同じに設定してしまったら、
必ずChildWindowが収まりきれなくて枠にクリッピングされてしまう。 >>225>>230
rect.right = 200; rect.bottom = 200;でAdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, true, 0);
としたらWidthは216に変わり、その通りにWidth引数を216にしてみたら丁度良くなりました。
どうもありがとうございました。 ツールバーについてです
x86 コンパイルで意図通り動作するのですが、
同じソースを x64 コンパイルだと変になっちゃいます。
ツールバー作成時にTBSTYLE_TOOLTIPSを指定
TB_ADDBUTTONS メッセージでボタンを追加
その際の TBBUTTON の iString に文字列 char* を入れる
その後に TB_GETBUTTONTEXT でそのボタンの文字列を取得するのが
x86 → 正常に追加した文字列が取得できる。ツールバーにツールチップが表示される。(特に問題無)
x64 → 追加した文字列は取得できず、空文字列になる。ツールバーにツールチップが表示されない。
TB_ADDSTRING メッセージで事前に文字列を追加して
ボタン追加時の TBBUTTON の iString にインデックスを入れる形だと
x86 → 上記と同じ問題無く動作する。
x64 → 追加した文字列が取得できる。しかし、ツールバーにツールチップが表示されない。
という状況です。何かこちらの不備等があったりするのでしょうか?
それとも Windows のバグか何か?回避策等はあるのでしょうか?
WM_NOTIFY の TBN_GETINFOTIP を処理すればツールチップ表示は可能なのですが、
それ以外に方法は無いのかなと。 >>232
iStringへのキャストで変なことしてない?
x64ではポインタ型と32ビット整数には互換性ないよ。 普通はTTN_GETDISPINFOかTTN_NEEDTEXTを処理するんじゃないの?
知らんけど >>233
iString は INT_PTR なので x64 だと64ビット長で互換はあるかと思います。
キャストは reinterpret_cast<INT_PTR>を使ってます。
>>234
ネットにあるいくつかの解説だとその通りなのですが
x86だと TBSTYLE_TOOLTIPS を指定したらそれだけで上手く行ったので
それでやってました >>232 の件もう少ししらべてみたら間違いがあって
TB_ADDSTRING メッセージで事前に文字列を追加で
iString にインデックスを指定するやり方でも x64での
TB_GETBUTTONTEXT で文字列は取得できませんでした。
要するに、x64だとツールバーのボタンに文字列を結びつけるのが上手くいかない感じっぽいです アプリハンガリアンまで有害に見えてくる
システムハンガリアンの害毒は計り知れない 現象を引き起こすコードを書いたファイルをアップしてみました。
x86のコンパイラとx64のコンパイラだと
メッセージボックスに出てくる文字列が異なるのと
ツールバーにマウスポインタを置いた時のツールチップの出る出ないの違いがあるかと思います。
https://dotup.org/uploda/dotup.org2184156.cpp.html >>239
SendMessage( hwndToolbar, TB_BUTTONSTRUCTSIZE, 20, 0 );
マジックナンバー使うなよ。間違いのもとだよ。 この場合はsizeof(TBBUTTON)を渡すことになる。 > メッセージボックスに出てくる文字列が異なるのと
x86がANSIでx64がUnicodeビルドになってたりしないか? たとえば、編集不要なアセンブルリストを表示して、デバッガでステップ実行するようにボタンをクリックして現在行を反転させながら表示したいとしたら、もちろんループやジャンプもあるのですが、どのコントロールを使用しますか?
行数は10,000位にはなります
自分でクライアント領域に書きますか? >>245
ありがとうございます
ListView について調べてみます ドライブ文字を変更したら、PdhAddCounterでLogicalDisikの
パフォーマンスオブジェクトを追加できなくなりました。エラーが返ってくる。
再起動してドライブ文字元に戻しましたがやはりダメです。
typeperf -qを実行してオブジェクトの一覧見てもLogicalDiskの項目がないです。
また取得できるようにするにはどうしたらいいでしょうか? 自己解決しました〜!
コマンドプロンプトからlodctr /rを実行すると
パフォーマンスオブジェクトを再構築出来てそれで大丈夫でした!
お騒がせしました。 学術の巨大掲示板群 - アルファ・ラボ ttp://x0000.net
数学 物理学 化学 生物学 天文学 地理地学
IT 電子 工学 言語学 国語 方言 など
simulationライブラリで純粋な関数式プログラミングをする
UIライブラリ (C#, 2D) を作ったよ
連続と離散を統一した!
4Dエンジン
matrixのライブラリ
ある強力なFor関数
SQLライブラリ
☆ VMを書いた(C# + DirectX) * x86ではない!
ttp://up.x0000.net/files/TSimulang.zip
☆ malloc / free を実装してみた (C#)
ttp://up.x0000.net/files/TMallocTest.zip winrt api は win32 api の上位互換という認識は間違いでさか? 多言語からの呼び出しに対応するためにメタデータに拡張の入ったCOMとでも思っておけばいいよ
APIによってはデスクトップから呼べなかったりするのもあるけど
Win32APIかどうかを議論する意味はない おまいらGetLastErrorの戻りやHRESULTからstd::system_errorを投げるのに何使ってる? https://docs.microsoft.com/ja-jp/windows/win32/medfound/mfcaptured3d-sample
ここのサンプルを使ってwebカメラのキャプチャをしているのですが、
サンプルを実行すると勝手にオートフォーカスになります。
Media foundationを使ってマニュアルフォーカスにしたいのですが、
やり方が分かる方はいらっしゃいますでしょうか。 IMEで確定前の入力をキャンセルされるにはどうすればよいでしょうか? >>257
自己解決しました
>>258
'ESCキーを押します' 関数は無かったですね。 画面右下に IMEのON/OFF状態が表示されていますが、これをプログラムで
取得する方法はありますでしょうか? >>262
大事な点として、自分のアプリでの状態ではなく、システム全体での状態が取得
したいということがあります。 >>263
メモ帳開く(A)
→半角状態にする
→もう一つメモ帳を開く(B)
→全角状態にする
Aがアクティブになると半角に
Bがアクティブになると全角に
後はわかるな? >>264
それは、現在アクティブな(フォーカスを持っている)アプリに依存すると言うことですが、
タスクバーの右下には、ON/OFFが出ているので、システムは現在、どちらの状態
かを分かっているわけです。
その状態を知る方法が知りたいです。 自分のアプリがアクティブじゃない時でも状態をリアルタイムで知りたいって事?
もしそうならフック そもそもIMEの設定でアプリ毎に切り替えるかシステム全体で切り替えるかを選ぶから
そっちも観ておかないと判断出来ない いや、キーボードはひとつなんだから難しく考えるなよ >>268
IMEをON/OFFするキーバインドは、複数種あることと、カスタマイズすれば、
変更することも出来るので、単に全角/半角キーが押された回数をトラッキング
していけば済むわけではないと思います。
ALT+全角キーだけで反応する流儀と、ALTを押さずに、全角キーだけ押して
反応する流儀もありますし。 ImmGetOpenStatus
まあ>267の言うとおりの問題はあるので、Windows全般でどうなっているのかという
判断が必要ならば仕様の見直しが必要 IMM32を実装できる方はReactOSを助けて下さい。 >>266
やはり、フックですか。
実は、この件でのフックでの実験は既にやってみて、成功したことがあります。
ただし、フックは、32BITと64BITで DLL を分ける必要があるため、
実験したのは、32BITのみでした。
64BITにも対応しなくてはならないので、手間がかかるので中断してます。 >>262
GetDC(null)で画面全体のdevice contextを取得
bitblt()で画面イメージをメモリーDCに取得
>画面右下に IMEのON/OFF状態が表示
の部分を画像比較でON/OFF状態を判定 >>273
キーボードフックならdll作らんでもいいぞ >>276
そうでしたか?
フックを始めるための API 関数名やフラグ定数名やモードなどを教えていただければ幸いです。 32bit用に描いたフックを64bit用に描き治すのってそんなに大変? >>279
普段使っている処理系が古くて、64BITに対応の処理系は、今まで使っていませんでしたので。 普通にsetwindowshookexでできるぞ
wmwareアクティブだとマウスとキーボードフック全部効かなくなるけどなんとかならないのかな キーボードとマウスのフックでモジュールのハンドルとスレッドid0だとdllいらない
ほかは駄目なのあるけど
あと64bitで作っておけば32bitのフックもわざわざしなくていい >>282
>あと64bitで作っておけば32bitのフックもわざわざしなくていい
これはもしかすると、32BITアプリの場合、64BITのDLLのフック関数を OS
が呼び出してくれると言うことでしょうか? 32bitで実験やったんなら移植もすぐだからやってみればいい
dll使わずにする場合も専用APIとか無いし >>272
成功して欲しいOSだけど、日本語入力で行き詰まってるんなら先は長そうだね
>>274
表示位置で取得ってタスクバーの位置が変動するから無理があるのでは
デザインが少し変わっただけでも死ぬ
>>277
IMEのON/OFFのキーバインドなんて環境で様々なんだからキーボードフックなんかじゃ実現無理なの分かれよ
アプリ側でもプログラム的にON/OFFするのに
そもそもアプリ問わずIMEの状態を取得する意味あるのか?何したいんだよ 意味があるかどうかは外野がとやかく言うことではない 意味の有無を聞いてるとしか読み取れないのはどうかと思う 素直に質問に答えりゃ良いんだよ
質問自体を疑問に思う必要などない 質問が間違ってるから答える気にもならないことはある どうせ32bitでなら実験したってのが嘘で試しようがないんでしょ その実験は、凄く上手く行きました、と言っておきます。 IMEのON/OFFはマウスやアプリでも出来るからな
そっちの対応はどうするんだろ 皆キーボードフックしか言ってないけど
IMN_SETCONVERSIONMODE捕まえればいいやん
それもやったってんなら64bit対応するだけやん ONはともかくIME入力中だとOFFしても入力中のIMEのうにょうにょが消えないのだが ONだと普通の数字は全角なのに
テンキーだと半角
ちゃんと分岐してるならテンキーのうにょうにょも無しにしたらいいのに おまいらGetCommandLineが返した文字列からコマンド名だけ除いた部分て、どうやって得てる? やっぱり自前でコマンド名だけ取り除くしかないのかな
空白や引用符に特別な意味を持たせたくないんだけど MFCならCCommandLineInfoなんだがな。 CreateProcess見るといろいろな指定の仕方ができそうで不安になるよね >>296
そんなの使わずにWinMainの3rdパラメータ使う /a //b /c:"text"
この場合b無視すんの? >>303
CWinApp::ParseCommandLine()は__argcと__argvを見ているだけだけどな 質問なんですがWindowsのカレントディレクトリって
アプリ毎に持ってるものなんでしょうか?
それとも全アプリ共通なのでしょうか? >>309
スレッド毎に違うんですね!ありがとうございました。安心しました。 >>312
自分がそうだからといって他人もそうだと思うのはよくないな MSDN によれば、正しいのはプロセス毎。スレッド毎ではない。
*SetCurrentDirectory
The SetCurrentDirectory function changes the current directory for the current process.
BOOL SetCurrentDirectory(
LPCTSTR lpPathName // new directory name
);
*Remarks
Each process has a single current directory made up of two parts:
・・・ ということは、同一プロセス内の別スレッドでSetCurrentDirectoryが発行されると
自スレッドのカレントがいつの間にか変わっているということが起きるのか カレントディレクトリの取得なんて、グローバル変数から情報を取ってくるようなもんなので危険ってことだ
そんなもん使うな >>315
もちろんそういうこと。
というより、カレントディレクトリも、広い意味で「UI」に関係したものと
考えられなくもないので、必ず Mainスレッドから取得するようにすれば、
安全と言える。絶対そうしなくてはならないわけではないが。
Window作製、グラフィック描画、マウス、キーボードからの入力なども、
Mainスレッドで行うのが原則。
これも絶対そうでなくてはならないというわけではないかも知れないが、
敢えて Subスレッドでやる意味も余り無い事が多く、Mainスレッドに限定
すれば、さまざまな危険回避のための余計なことを考えなくて済むメリットがある。 >>317
補足すれば、カレントディレクトリは、MS-DOS時代では、command.com
が管理していたもので、アプリごとに異なるわけではなかったはず。
というのは、カレントディレクトリを便利に変更できるツールを作りたい
場合などに、アプリローカルであれば、不便だったからだと思う。
その設計哲学や文化や習慣が、Windowsにも受け継がれる必要は有ったと思う。
Unixの環境変数なども、アプリローカルになっていたりするが、意外と不便な
事も多い。 何を根拠に長文をw
INT21 AH=3B の説明を読み直し要 >>315
>自スレッドのカレントがいつの間にか変わっている
自分で管理できないスレッドなんてあるのか?
その別スレッドだって自分で作ったものだろ?
DLLとか自分で管理していないものもあるけどそれはスレッド関係ないわけだし DCE-RPCは電文受信すると勝手に
処理スレッドたててくれるよ >>320
別スレッドにするってことは自スレッドとの間にタイミングの束縛がない処理を任せるってことだよな
カレントディレクトリの変更がプロセス内の他のスレッドにも伝搬するということは
それはタイミングの束縛が生じうるってことだろ
つまり、それが困るなら別スレッドにしてはならない処理内容ってことで
そこの判断こそが「自分で管理」ということだ スレッドがお互いを信用できないとか、そんな羅生門みたいなプログラムは嫌だなぁ。 指定フォルダ以下のファイルをすべて処理するプログラムで
サブフォルダごとにスレッドを起動してみよう そんなバッチファイルみたいなアルゴリズムでカレントディレクトリ移動しながらマルチスレッドをやるとかがそもそも迂闊だよな。 >>329
マルチスレッドじゃなくてマルチプロセスなら作業ディレクトリは完全に分離できる。
せっかくマルチタスクOSを使っているのだから、別プロセスに丸投げするのが最適だよ。 タスクマネージャー開けばわかるけど、今時のWebブラウザ(具体的にはEdgeやFirefox等)はたくさんの子プロセスを動かしている。 sse2までが必須になったのはいつだったか覚えませんか
win-7の途中くらい? win32apiを使っている人は、普段の文字コードは
stringとwchar_tを使っているのでしょうか。 ありがとうございます。
調べてみます。
stringを使いたいのに、win32apiは変換が必要?なので躊躇しています。 CreateProcessのユニコード版(W)の第2引数がリテラルだとうまくいかない件
これはハマったわ。
CreateProcess(TCHAR)でメモ帳起動させるサンプルで
_T("C:\\Windows\\notepad.exe")を直接与えてもCとしてコンパイルするとうまくいってて
c++にしたら起動しなくなったが、エラーが出ないから全然気づかなかったわ
ネットのCreateProcessのサンプルも普通に与えてるしなあ
考えてみれば実運用でこの部分は文字リテラル決め打ちにめったにならないから
知らずに回避してることも多いのかも LPTSTR で受け取ってるから書き換え可能なメモリアドレスでないとあかんのじゃないのん?
リテラルは const で書き換え不可だし 一回変数経由しないと 自転車🚴のような絵文字をstd::stringで持つにはSJISではなくUTF-8として保持しておいて、
画面などの出力する直前にUTF-8からUTF-16に変換してUnicode版出力関数を呼び出す必要がある。 >>339
>lpCommandLine
>実行するコマンドライン。
>この文字列の最大長は、Unicodeで終了するnull文字を含めて32,767文字です。 lpApplicationNameがNULLの場合、lpCommandLineのモジュール名の部分はMAX_PATH文字に制限されます。
>この関数のUnicodeバージョンであるCreateProcessWは、この文字列の内容を変更できます。
>したがって、このパラメーターを読み取り専用メモリー(const変数やリテラル文字列など)へのポインターにすることはできません。
>このパラメーターが定数文字列の場合、関数はアクセス違反を引き起こす可能性があります。 >>339
argvに渡すから非constだぞって話か 非 const の引数に const リテラル与えたら
コンパイルエラーにならないか? それがエラーになるなら固定文字列を渡せなくなるやん >>346
C++11以後、そうなった筈だけどcl.exeはversion 19.27.29111でも通す(もち/W4で) Win32API全部作り直してほしい
くだらない部分で人間の時間を消費しすぎだろw >>349
自分でラッパーでも作ればいいんじゃね?
作れない低能なら諦めるしかないだろうけど 穴がさらにいっぱい見つかって攻撃方法が増えるんだから自明だろ
誰が対応するんや 久しぶりに Windows Update したら
Edge レイプされてポカーン _beginthreadexだけは許さんよ
もっとも醜悪な名前だわ http://eternalwindows.jp にはWin32の核心部分が載ってる。参考になる記事だ。 GetOpenFileName で初期ディレクトリとして OPENFILENAME の lpstrInitialDir に
任意のディレクトリを指定してファイルを開くダイアログを開いていて、おおよそ
意図した通りに動いているのですが、"C:\Users\Public\Documents"を指定したときだけ
初期ディレクトリが現在使用中ユーザーのドキュメントディレクトリになってしまいます
アクセス権のない他のユーザーのドキュメントディレクトリを指定したのなら
このような動作は理解できるのですが、パブリックディレクトリでこのように
なってしまうのは仕様でしょうか? パブリックディレクトリの取得方法を聞いているわけではないのですが
"C:\Users\Public\Documents" は存在する有効なパスです 再現した
C:\Users\Public
ならちゃんと public が開くが
C:\Users\Public\Documents
にすると自分のアカウントに行ってしまう あと存在しないディレクトリを与えると
C:\Users\自分のアカウント\Documents
が開いた lpstrInitialDir
The initial directory. The algorithm for selecting the initial directory varies on different platforms.
Windows 7:
If lpstrInitialDir has the same value as was passed the first time the application used an Open or Save As dialog box, the path most recently selected by the user is used as the initial directory.
Otherwise, if lpstrFile contains a path, that path is the initial directory.
Otherwise, if lpstrInitialDir is not NULL, it specifies the initial directory.
If lpstrInitialDir is NULL and the current directory contains any files of the specified filter types, the initial directory is the current directory.
Otherwise, the initial directory is the personal files directory of the current user.
Otherwise, the initial directory is the Desktop folder.
Windows 2000/XP/Vista:
If lpstrFile contains a path, that path is the initial directory.
Otherwise, lpstrInitialDir specifies the initial directory.
Otherwise, if the application has used an Open or Save As dialog box in the past, the path most recently used is selected as the initial directory. However, if an application is not run for a long time, its saved selected path is discarded.
If lpstrInitialDir is NULL and the current directory contains any files of the specified filter types, the initial directory is the current directory.
Otherwise, the initial directory is the personal files directory of the current user.
Otherwise, the initial directory is the Desktop folder. comdlg32.dllのコモンダイアログ関係は >>367 のような想定外の動きをしたり
右クリックのコンテキストメニューで存在しない32bitフォルダを探しに行ったりと色々不具合を抱えてる
明らかにメンテされてない
ダイアログ内のListViewで開発者の想定外の事ができたりするから許されるなら使わない方が良い コモンコントロール使ってるアプリに使うなと言ってしまうと、開発プラットフォームから見直さないとダメ案件では >>372
> Otherwise, the initial directory is the personal files directory of the current user.
この分岐に填まってるようですが、lpstrInitialDir が NULL でない以上おかしいですよね
とりあえず仕様ということで対応します
ありがとうございました
>>373-374
確かに他にも怪しい挙動があるので差し替えたい所ですが、そんな単純にコモンコントロール部分だけ
差し替えが可能なものがあればいいのですが・・ XP 以前と 7 で違うんだから
10 ならさらに変更されたとかありそう >コモンコントロール部分だけ差し替えが可能なもの
秀丸ファイラーのdllって無かったかな こんにちは、お世話になります。DLLファイルの削除について質問です。
プログラム終了時にロードしたDLLファイルを削除したいのですが、
場合により削除できたりできなかったりします。
実際にはもう少し複雑ですが、大まかな処理の手順を示します。
1: inst=LoadLibrary("tmp.dll")
2: hook=SetWindowsHookEx(...)
3: ...あれやこれやの処理...
4: ret1=UnhookWindowsHookEx(hook)
5: ret2=FreeLibrary(inst)
6: ret3=DeleteFile("tmp.dll")
処理部[3:]は、所望の通り動作していて、inst,hook共に正常値のよ
うです。アプリケーション終了時に[4:]以降の処理を行います。ret1,
ret2は成功値を返すのですが、ret3は失敗し、GetLastErrorの値は5で
ERROR_ACCESS_DENIED「アクセス拒否」を返してきます。アプリ
ケーション終了後はプロンプトからのDELコマンドに成功します。
処理部[3:]をスキップすると、ret3は成功値を返しファイルもただ
しく削除されています。
FreeLibraryだけでは、DLLを開放してくれないのかと思っていますが、
少し手つまりになっています。当方、日曜プログラマレベルの知識で
す。質問などに不備等ございましたらご指摘ください。
(環境)Win10-64bit,Vs2019Comm,VC++ 追記
2: hook=SetWindowsHookEx(WH_KEYBOARD_LL,proc,inst,0)
フックにDLLインスタンスが絡みます。 1〜2をやるボタンAと
4〜5をやるボタンBを配置して
ボタンBを押してから6やってみた? >>381 ありがと
いや、そういう処理の分解はやってないです。
ただ、[5:]と[6:]の間にSleep(10000)を挟んでみた。OSが手放してくれる時
間?が必要かと思って・・・でも、そういう事じゃないみたい。
ボタンの配置はすぐには難しいですが(汗)。でも、とりあえず、物は試しで
ユーザの入力待ちを挟んでみます。getch()あたりで・・・。 あと 6 だけ実行する別のアプリを造っておいて
アプリ終了後にそれを呼ぶとか 379です。進展しそうなので、この質問はいったんクローズさせてください。
グーグル先生に「dll_process_detach 呼ばれない」と聞くと、イロイロ出て
きそうです。
381、383 ありがとうございました m(_ _)m 呼び出しプロセスが終了するまではDLLの解放はされなかった気がする
つまり>>384が正解なのではないかと 32bitアプリからShellExecuteでバッチファイルを呼ぶと当然ながら32bit環境で実行されるんだけど
これを64bitに強制できないかな >>389
Wow64DisableWow64FsRedirectionを使う痛い方法があるけど、推奨できない。64bit processを経由した方が痛みは少ない。 でてきた
PVOID m_lpOldVar = 0;
Wow64DisableWow64FsRedirection(&m_lpOldVar);
//この間に書けばいいらしい
ShellExecute(hWnd,"open","cmd","param","dir",SW_SHOWNORMAL);
Wow64RevertWow64FsRedirection(&m_lpOldVar);
これでいいのかな? ほんとは32bitアプリを64bit化すりゃいいんだけど思いの外大変なので諦めた
以下バッチ側で判定する方法
@echo off
if %PROCESSOR_ARCHITECTURE%==x86 (
if "%PROCESSOR_ARCHITEW6432%" == "AMD64" (
rem 32bit WOW64
C:\Windows\sysnative\cmd.exe /c %~dp0%~n0%~x0
exit /b 0
) else (
goto :PASSX64
)
) else (
goto :PASSX64
)
:PASSX64
以降x64前提の処理 リダイレクトを無効化して、system32のcmdを指定すればいけるやろ。 プロセス起動だけを担当する小さな64bitアプリを作ればいいじゃない。 379です。
LoadLibrary()でロードしたDLLが呼び出しプロセスから削除できない件のご報告。
方法が正しいのか悪いのか(不具合を発生させる可能性を持つのか)わかりませんが、
削除することには成功しました。383さんがご指摘の「DLL_PROCESS_DETACH
が呼ばれてないんじゃない?」とMSDNのFreeLibraryの文書をヒントに、
FreeLibrary()がゼロを返すまで複数回繰り返す方法で対処できました。DLLモ
ジュールへの参照数が無くなった時点でDLL_PROCESS_DETACHが発生するよう
です。また、ゼロを返した時のGetLastError()値は126(ERROR_MOD_NOT_FOUND)
です。
適当にいじりながらモニタしてみるました。すると、DLL_PROCESS_ATTACHは
1回しか呼び出されていないにもかかわらず、DLLモジュールは1または2の参照カ
ウントを持っているようです。どのタイミングで2になるのか、また3回目が発生
しないのかは、追い切れていません(汗。エラー検出で正常・・・的な行儀のよい
コードとは思えませんが、とりあえず、要モニタリングで先に進みたいとおもいま
す。
このあたり、お詳しい方がおられましたらご指導いただけると助かります。今のと
ころ困ってはいませんので、お暇なときにでも^^。ありがとうございました。 >FreeLibrary()がゼロを返すまで複数回繰り返す
なるほど
自分以外が使ってないことが確実に言えるならこれで良いんじゃないかな 実は自分で 2回 LoadLibrary してましたというオチですね判ります ズコー
LoadLibraryをAPIHookしちゃおうぜ 長文で申し訳ない。
396
自分しか使っていないDLLであることは間違い無いので・・・とりあえず現状で
すすめる感じ。動いてるからOKは無能感アリアリです。リファレンスカウント
を追いかける事もできるようですが、沼入間違いなし。もし3回目が発生したら
ワーニング出してるので、報告してもらいます。ありがと。フックの時、DLLイン
スタンスを与えてるので、その時、参照が追加されるのかな、などと妄想するわけ
です。
297
判りますか!・・・さすがです。あおりでないと思ってマジレス。
ユーザの起因でLoadLibraryが2回実行される可能性として思い当たるのが:
1.メインプロセスが終了していないうちにデバグなどで再度起動しちゃった。
2.LoadLibrary呼び出しのの箇所をプログラムカウンタが2回通過している。
辺りでしょうか。1は、多重起動が排除されていて、かつタスクマネジャにも出て
いないので可能性が低い。2は、ブレークポイントとprintf()でモニタしてて多分
ないかなぁ。他アドバイスありましたらよろしくお願いいたしますm(_ _)m。
398
LoadLibraryをフックして、どのタイミングで呼び出されるのかを理解する感じ
ですか?APIフックかぁ・・・経験値が足りないのでハマりそうだなぁ。thx。 >>395
FreeLibrary()は何回呼び出して何回目でゼロが返ってきてるの? 400さん、レスありがとう。実際のコードはi値の制限などもちっと複雑なので
すが、感じとしては、WinMainに以下のように記されています。
1: i=0;
2: for(;;) {
3: i++;
4: ret=FreeLibrary(dllinst);
5: if(res==0) {
6: n=GetLastError();
7: break;
8: }
9: }
場合によるのですが、ループを出た時のi値は2か3を示します。nは126です。
i値が2になるケース、3になるケースは、初回投稿 >>379 に示してあります。
フックの初回呼び出しにリファレンスが追加・・・かなぁ(妄想。 >>401
4でretなのに5でresなのは誤字かな? というか>>379でいうと
> 3: ...あれやこれやの処理...
ここに原因があるってことでしょ
そこ次第じゃないの? まず>>379の1の直前・直後での山椒カウンターから調べてみるとか LoadLibraryの参照カウンタって簡単に取れたっけ?
昔DDKのヘッダ持ってきてゴニョゴニョやった気がする。
しかもwin7と8以降で構造体定義が違ったり。 成功するまで n回 FreeLibraryを試みて LoadLibrary しなおす?
ATTACH と DETACH が副作用おこすかもだけど みなさん、こんな漠然とした質問に答えてくださってありがとう。
404さん、405さん。参照カウンタの取得は、現象の理解に役に立つとは思います
が・・・なにぶん日曜プログラマなものですから。
google先生 「win32api how to get dll reference count」
でめぼしい情報はPEB(Process environment block)のLDR_MODULE構造体がう
んちゃらで(マト違い?)、ハードルの高さを感じました。
406さん。おっしゃる通りです。ユーザーのコード内でLoadLibraryが1度だけ
呼ばれるのだけど、参照カウンタが2になっている点は重要と認識しています。
3になるかもしれないし、いつ増えるかも妄想の範囲を出ません。FreeLibrary
するループ内で参照カウンタが変化かもとかゾッとします。
というわけで、今のところ警告を出して他の現象も集めてみたいと思っています。
が、人に使ってもらうレベルでは、参照カウンタの振る舞いは押さえておかないと
いけないという認識です。 追記:
LoadLibraryが2度呼ばれてましたとかいうオチの時は、正直に詫びを入れることを
お約束いたします。いやマジで、ユーザーコード全部で記述は1ヶ所だけし、2回通っ
てないし(大汗。 LoadLibraryしたライブラリの名前は何ですか? exeと同じディレクトリに置かれたtmp.dllという名前です。DLLによっては、
参照が増える可能性があるということでしょうか。私が書いたコードですが中
身はほぼ空っぽです。たまにデバグやモニタの為にprintfします。コピペで手
加工のためtypoしてたらごめんなさい。
* tmpdll.cppの中身
01: BOOL APIENTRY DllMain(
02: HINSTANCE hinst,
03: DWORD reason,
04: LPVOID rsv
05: ) {
06: switch (reason) {
07: case DLL_PROCESS_ATTACH:
08: DisableThreadLibraryCalls(hinst);
09: break;
10: case DLL_PROCESS_DETACH:
11: break;
12: case DLL_THREAD_ATTACH:
13: break;
14: case DLL_THREAD_DETACH:
15: break;
16: default:
17: break;
18: }
19: return TRUE;
20: }
* コンパイルコマンド:
>cl.exe /LD tmpdll.cpp User32.lib
>move tmpdll.dll tmp.dll
すいませんが、今日はもうレスできません。作業は停滞から抜け出れてますので、
どうかヒマつぶし程度の軽い気持ちで受け答えください(大汗。 参照カウントは、読み込んだ・実行した回数と関係ないだろ。
複数のプロセスから、参照されていれば、2 以上になるだけだろ
自分が参照すれば1で、
OS も参照すれば、2じゃないの?
自分で参照回数を、0にすべきじゃない。
OSが使っているかも知れないし
OSが何をやっているのか、勉強していない香具師は、妙な事を考えない方がよい。
OSの勉強だけで、何十年も掛かるから ウイルス対策ソフトによる介入まで考えたらさらに増える。 >>411
ここで言ってるのはプロセス内の話だぞ?
LoadLibraryを2回やったらFreeLibraryも2回呼ばなきゃならんという話。
>OSが何をやっているのか、勉強していない香具師は、妙な事を考えない方がよい。 DLL を2回も呼ぶのか?
一々、DLLをロードしてから、フリーするとか、
そんなに厳密に、メモリを気にしなくても良いのでは?
初心者は、そんな些末な事に、時間を掛けるべきじゃないと思う。
どうせ、1MB とか、ほぼ64 bit では無意味な節約だろ
そういうのを気にしていたら、Ruby などでプログラミングできない。
皆、富豪プログラミングなのにw LoadLibraryの参照カウンタはプロセス単位
質問者はDLL_PROCESS_ATTACHが複数回呼ばれると思ってるようだが複数回LoadLibraryしても呼ばれるのは最初の1回だけ おはようさん。ゆるくいってもらえるとうれしい。
413さん。LoadLibraryを複数回呼べば参照カウンタはそれだけ増えます。
その場合、増えた原因がLoadLibraryと明らかなので特に問題ないと考えます。
わからないのはLoadLibraryが1度のつもりなのに、場合によって一つ増える
現象が不思議だなってあたり。
414さん。まったくその通りです。実際、削除してみたいというのは今のところ
技術的な興味だけで、参照カウンタの増加原因がコードのどの部分なのかが
わかれば自分が面白いという点だけです。対応策は削除しない策も含めて2、3
考えていて重大ではなくなっています。時間がもったいないですね。
461さん。アプリケーションが起動されたプロセスで、DLL_PROCESS_ATTACH
はLoadLibraryの時に1度、DLL_PROCESS_DETACHはFreeLibraryにより参照カ
ウンタが0になった時に1度だけです。このように理解していますが^^;。
参照カウンタはプロセス毎に持っていて、自プロセスのFreeLibraryが2回成功
するということは、自プロセスの参照カウンタが2になっていると考えていま
す。他のプロセスがtmp.dllをロードしても、自プロセスの持つ参照カウンタは
増えません。予想の範囲をでませんが、自分の書いたコードの中のあるAPI関数
が参照カウンタを増やしている、たぶん初回のフックプロシジャ起動の時に増え
てるっぽい。ですので、現象を正しく理解するには、結局の所、参照カウンタを
モニタして増減のポイントを押さえ、可否を判断するのが本道かなとも思います
・・・難しそうですよね。APIは勝手に参照カウンタ増やすよ?なんてアドバイ
スがあると、よかったのですが。
長文でくどくなって、イラついている人がいそうですね。この辺で、一度この話
題から私は離れたいと思います。アドバイスくださった方がた、どうもありがと
うございました。 自発的なdllの削除ってなると >>412 の件は厄介かもな Windows は、クローズドOS だから、何をやってるか分からない
ファイルをロックするためにとか、メモリから追い出されないために、
参照回数を増加させるかも知れない
だから、自分が1回しか呼んでいなのなら、参照回数を2回減らしてはいけない。
2回減らしても、無視されるだけかも知れないけど
自分が増やした分だけを、減らすべき! なんか参照カウントと単なるカウンタが入り乱れてそうな流れ 全部読まずにresするが
元々自分のexeの依存dllにそのdllを入れちゃってるのに
さらにLoadLibraryしてるとかかな DLLのコードもあるなら別にDLLで無くてもいいのではと思ってしまうw >>421
俺もそう思う
静的リンクと動的リンク合わせて2回呼ばれていると思う なんか滅茶苦茶だな
古いMSDNライブラリ2008ではshellコントロールもCE5.0も正しい定義が出てる
メンテ止めても表示崩す必要無いだろに...
https://docs.microsoft.com/en-us/previous-versions/windows/embedded/aa453326(v=msdn.10)
久々にapi使ってコード書こうかと思ったがガックリだわ ListView_GetItemCount
Retrieves the number of items in a list-view control. You can use this macro or send the LVM_GETITEMCOUNT message explicitly.
int ListView_GetItemCount(
HWND hwnd
);
Parameters
hwnd
Handle to the list-view control.
Return Values
Returns the number of items. なぜですか?
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13212452128
質問者からのお礼コメント
小学生でもわかるような回答ではなく、なぜそうなのかも回答できないと社会人として微妙ですよ。
わかる箇所だけ答えるのはニワカです。 AllocConsoleでコンソールを開いてそこからstdio.hのscanfしたいのですが、
ノンブロッキングではないので呼び出し側が固まってしまいます。
そこでscanf的な機能をもつノンブロッキングな関数をつくりたい。
FILE_FLAG_OVERLAPPEDでCONIN$を開いてReadFileで読むまではいいのですが
ReadFileしていない間の入力もバッファリングしてしまいます。そういう機能だから当然ですが。
このバッファリングをうまくオンオフする方法、もしくはバッファを棄てる方法はないでしょうか?
それともFILE_FLAG_OVERLAPPEDではない別の方法があるのでしょうか? CONIN$を開いたハンドルをCloseHandleで閉じたりFlushFileBuffersしたりは試しました。 >>434
ありがとうございます
sscanfはもちろんするのですが、その前段階、文字列を読み込む部分が上手くいっていないのです。 setvbufやfreopenはcランタイムの関数で、バッファもOVERLAPPEDのバッファとは違う気がします
freopenしたstdinからのscanfがブロックされてしまうというのが443の話なので
そこからノンブロッキングのAPIを使う必要があるのでは、ということになったわけです ReadConsoleってAPIもブロッキングなので使えないわけですが、低レベルなReadConsoleInputというのもあるらしく
OverlappedでのReadFileよりこっちの方が正攻法なようです。
ともかくやってみます。
ありがとうございました。 >>433
プログラム側で「この時点以降の入力を有効とする」タイミングは管理してないの?
その時点でバッファされてる物を一旦読み捨てれば良いだけでは? 生のコンソールは制約が多いから
コンソールアプリの入出力を奪って適当なコンソールもどき作った方が早そうだけど スレッド作ってブロックさせておけば良いと思うんだけど
正直な話>>442
バージョンによって微妙に動きが異なるし >>443
ありがとうございました
ブロックしないじゃなくてブロックしても大丈夫にして上手くいきました
バッファの方は事前にFlushConsoleInputBufferで解決しました コマンドプロンプトのコンソールを使う案件は、スクリプト言語とのプロセス通信を使ったほうが幸せになれる確立が高い。 GetProcAddressってAやWないよね?
それでいてwcharでもcharでも機能するのは仕様? __declspec(thread)の変数ってスレッドごとに記憶域をもつわけですが
APIのTlsGetValue等でどうやって実現してるんでしょうか?
TLSインデックスをうまくスレッドハンドルと結び付けなけりゃならないと思うんですが。 正直、このあたりは深く考えないことをオススメするのですが。
興味があるということであれば↓を参照しつつ。
http://www.interq.or.jp/chubu/r6/reasm/PE_FORMAT/6_6.html
コンパイラが__declspec(thread)の変数があった時に、どのようなコードを出力しているか
逆アセンブルしてみると理解が深まると思われます >>449
ありがとうございます
昔はTlsGetValueを使ってたのが、今はセクションが新設されてそこに作ってるんですね VirtualAllocとHeapAllocの違いについてなんだけど
HeapAllocもヒープ残量以上のサイズを渡したらどの道VirtualAlloc呼ばれるって認識でいい? HeapCreate以上のメモリはHeapAlloc
からは作れない。 >>452
ある程度大きいサイズのメモリ確保だとVirtualAllocの方が早くなるからそう勘違いしてたけどそういう訳じゃないんだね
最初に実際にアクセスした時に初めて実際にメモリ割り当てが行われるとかの挙動がHeapAllocでも走るってだけか virtualの方がよりローレベルなので
チャンクアロケーターをMSのレベルを
超えて作れるか、ほぼ解放しない前提
のブロックを確保するとかでないと使わない。
普通のmalloc風に使うなら、ヒープ領域毎
あぼーん出来るCreateHeapの方が使い易い あるstaticなlibが既存の場合(.hで関数の引数がTCHAR *使用)
それがANSI用にコンパイルされたlibなのか
それともUNICODE用にコンパイルされたlibなのか
既存のバイナリのlibだけから判断する方法はありますか?
#ソースは.cppでTCHARで書かれているものがあったので
#そこから-DUNICODEであらためてコンパイルすれば解決はしたのですが
#上の質問の解決策があるなら知りたいです >>455
C++の場合なら、ライブラリをdumpbinなどで調べて関数のマングリン化名を見れば分かる。
plain Cの場合は、実際にライブラリに1文字が2バイト以上のUNICODE文字を送ってみて、
正しく動作するかどうかテストしてみると分かる。 >>456
plain C の場合、他の方法としては、
1. dumpbinでライブラリ関数を逆アセンブルしてみて、引数の扱いがbyteに
なっているか、wordになっているかを調べれば分かる。
2. ライブラリの関数を呼び出すコードを書いてみて、デバッガで、ライブラリ関数の
中を逆アセンブルする。 もしかしてマングリの PEB_W とかのが UNICODE 用ってことでしょうか? >>458
デマングラー
なるものが(ブラウザ上アプリとして)ネットであって、関数のシンボル名
を入れると関数プロトタイプ宣言に直してくれるので試すべし。 VCにはundnameというツールが標準でついてくるし、gccにはc++filtがある STDAPI と __declspec(dllexport) を同時に使うと怒られるんだけど
原因は何が考えられますか?
__declspec(dllexport) を使わずに .def ファイルで .dll を作成することは可能なのですが
.def を使わずに __declspec(dllexport) で .dll を作成しようとすると失敗します STDAPI は 暗に extern "C" を含んでてでマングリングなしの素
C++で _declspec(dllexport) の場合マングリングする
それで衝突してるんでないの? Windows10環境、お互いに管理者権限ありでPostMessageしても反応してくれないソフトがあったのですが
互換モードでWindows7を選択すると反応してくれるようになりました
そこで疑問に思ったのですがこの違いの原因は何でしょうか? >>468
http://home.att.ne.jp/delta/hrymkt/PTIPS/UACvsAPI.txt
>PostMessage は 同じプログラムでも 一方が管理者権限で走っていると此にそのソフト特有の
>メッセージの ポストも出来ません。
>個々の メッセージは 受けとる方で ChangeWindowMessageFilter API で指定すれば受けとる様に出来ます。 ここを見ている人のために念のため貼っておくよ。ご参考に。
Win32のリファレンス マニュアル
Win32.chm http://laurencejackson.com/win32/
右クリックして「プロパティ」を選び、「許可する」をクリックして「OK」ボタンを押せばセキュリティのブロックを解除できます。 >>469
ありがとうございます
そのページは私も確認したのですがお互いに管理者権限ありなので下記に該当すると思います
>自身が 管理者権限で走っていれば この制限は無くなります。
ポストに成功する互換モードでもお互いに管理者権限ありなのでWindows7と10の違いが原因だと思ったのですが具体的に何が違うのか分からず… 64bitと32bit混在とか
LONG/HWNDの長さ違いとか やんわりとrustに移行させようとしてるマイクロソフト フルパス以外でのファイル固有のユニーク値ってBY_HANDLE_FILE_INFORMATIONのnFileIndexHigh、nFileIndexLow以外に何かない? GetOpenFileName()でファイルを開くダイアログが使えますが、
https://dotup.org/uploda/dotup.org2378520.png
このダイアログの赤枠内のように、チェックボックス等が追加されたカスタムのダイアログはどのようにすれば実現できるのでしょうか? >>478
FILE_ID_INFOのFileIdで128bitに拡張されてるな >>482
まさにこれです!
ありがとうございました! >>479>>481
膨大な量のファイルを列挙するにあたってハッシュ計算するのも、ハンドル開いてBY_HANDLE_FILE_INFORMATION読み込むのも億劫だったんだが
NtQueryDirectoryFileでmftからファイルID取れるってことに気付いた 画像ビューワまだできないの?
みんな待ってんだから コントロールパネルでフォントを「非表示」にすると、言語に応じて
フォント選択画面に出てこなくなり選びやすくなるという機能があります。
この「非表示フォント」かどうかを判別する方法はありますでしょうか?
ChooseFont()ではなくEnumFontFamiliesEx()を使い、独自のフォント選択ダイアログを作成中ですが
非表示フォントを判別する方法がわからずすべて列挙してしまいます。 >>486
レジストリ設定によるらしい。
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Font Management
https://visualstudiomagazine.com/Peterson1110?m=1 >>487
ありがとうございます!
レジストリに「非表示フォント」の一覧が記録されているのですね。
その内容を取り出して比較してフィルタリングしたいと思います。 ExpandEnvironmentStrings() は、%環境変数%を展開してくれるけど、
PowerShellの$env:環境変数 を展開してくれるAPIとかないのかな? >>489
[Environ]::ExpandEnvironmentVariables($env:環境変数) 2021/02/10
WindowsのTCP/IP実装に複数の重大な脆弱性、今月のセキュリティパッチはかならず適用を
ブルースクリーンが引き起こされるサービス拒否(DoS)脆弱性はすぐに攻撃が出回る可能性
https://forest.watch.impress.co.jp/docs/news/1305583.html Win32の質問というよりOSの仕様に近い質問になってしまいますが、
新しくファイルを作るにあたり予めファイルサイズが分かっている場合、SetFilePointerEx&SetEndOfFileで予めファイルサイズを決めておくと断片化しづらいというテクニックがありますが
一度のWriteFileで一気に書き込む場合は上記の工程を行わずとも断片化しづらいのでしょうか? 本当にそんな制御になっているか分からないけど理屈だけだと、最初に一発ここまで
使うよって宣言しておけば領域が一挙に確保されるかもしれない
逐一書き込みを行ってその度に領域を確保すると、システム全体がシングルスレッドで
動いていれば(ありえないけど)、自分が書き込みを行っている間に別の
プロセス/スレッドが書き込みを行うと、領域が分断されると思うのだけど 断片化対策というか
常に同じセクタに書き込むように出来なかったっけ? 高速ファイルコピーのフリーソフトの作者のブログか何かでこんだけWindowsのコピーは大変だよみたいな記事を読んだ覚えがある これやな
ttps://m.facebook.com/dnobori/posts/2142836202459674 結構読んだと思ったらまだスクロールバーが半分で、うんざりして読むのとWindowsでファイルコピーするのをやめた リーナスですらもNTFSが現状ベストって認めてるくらいだからその分複雑なんだろうね ほとんどの環境で特にエラーは出ないのですが
特定の環境でSHFileOperation()をFO_COPYで呼ぶとERRORONDESTが返ってきます
ファイルが使用中で書き込みできない場合は別のエラー、
ファイルではなく同名のフォルダでも別のエラーとなり
エクスプローラで手動でコピーは可能です
コピー元は全て英語のD:\AAA\BB.exe, コピー先は%temp%\AAA\\BB.exeを展開したもので
C:\Users\Username\AppData\ocal\Temp\AAA\\BB.exe
リトライしても改善しません
SHFileOperation()でERRORONDESTが返る要因てどんなのがありえそうですか pFromとpToの末尾は'\0'が2つ必要だけど忘れてない? pTo はダブルにする必要なくて pFrom のみじゃね?
複数個のファイル名を \0 をセパレータにしての連結して渡す意図かと
pFrom "fileA\0fileB\0fileC\0"
pTo "dir\\"
fileA,fileB,fileC を dir\ へ >>501
すみません、バックスラッシュはコード上は正しかったです
ちなみにスラッシュが足りない場合は0xA1 指定されたパスは無効です が返ります
多い場合は0xb7 既に存在するファイルを作成することはできませんとかが返ります
>>502
'\0’は末尾に4個以上はいれてます
FOF_SILENTは無効にして試しているんですが、有効にして書き込み禁止のファイルを上書きしようとすると
0x7cシステム コール レベルが間違っていますがかえります
この環境では、0x10000:ERRORONDESTが返るんですけど、
ほかの環境でERRORONDESTが再現できないんですよね.. >>499
あわしろ氏は、NTFSは欠陥品と言ってたけどな。 >>504
FOF_MULTIDESTFILES を指定した場合はどうなるの?
というか、まず C:\Users\Username\AppData\ocal\Temp\AAA というディレクトリじゃなくて
決め打ちでコピー先を D:\BBB\BB.exe って指定してうまくいくかどうか試してみたら?(D:\BBB というディレクトリは作成しておく)
これで失敗すれば関数の呼び出しに問題があると言えるし
成功すればその C:\...\Temp\AAA というディレクトリに問題がある >>506
決め打ちでパス指定してもダメでした
というかどこからどこにコピーしても全部ERRORONDESTのエラーになります
問題あるのは特定のPCだけで、他のPCだと問題なく動作するので、
何か変なソフトに邪魔されているかもしれません
もうだいぶあきらめ気味ですが、解決したら続報のせます
回答くれた人ありがとう エクスプローラの手作業ではコピーに成功してるらしいんだよねぇ 特定のも含めてPCがそれぞれどんな構成か出さないとエスパー案件になりそう
windowsがunicode設定だったり実はバージョン違いとかとか GetFullPathNameW() に C:\ ではなく C: を渡すとどんな文字列が返ってくるのかお教えください fopen()に環境変数、例えば %VARIABLE% を含むパスを渡した場合、
fopen()の側で環境変数を展開してからファイルオープンするかどうかって決まってますか? >>514
環境変数は@自分で目的のものを入手して、A自分で展開するしかない、かと fopen()はWin32APIじゃないから、決まってないんじゃないの? 決まってるという言い回しがアレだが、仕様としては>>515なのではないか
GetEnvironmentVariableとかExpandEnvironmentStringsとか使えと
つーか、511にせよ514にせよ自分で試せよ
内容からして同一人物か? 便乗だけどREG_EXPAND_SZ属性のレジストリの文字列って適当なAPIで取り出す時には展開されてる事を期待していいのかな fopen()つまりCreateFile()の環境変数展開の仕様が決まっているのならその文章のURLを貼ればいいだけで、そういった文章がないということは決まってないということだろう。 環境変数を展開するというなら%が含まれるファイル名の時は%をどうエスケープするの?
CreateFileのリファレンスに書いてある? >>520
そういった文章がない=展開しないと決まっている じゃないかね >>518
ローカル環境で試すことに意味はない
重要なのは仕様だけ
>>521
みたことない そもそもWin32APIはコマンドプロンプトのシェルに依存すべきではないから%VARIABLE%を勝手に展開するのはあまり好ましくない。
PowerShellやbashの書式で環境変数展開できないのは不公平になる。 >>520
>fopen()つまりCreateFile()の環境変数展開の仕様が決まっているのならその文章のURLを貼ればいいだけで
お前が自分で探してこいよ
何言ってんだこいつ 書いていることが仕様であって、書いてないことは仕様ではない
CreateFileでパンが焼けないと書いていないからパンが焼けると判断するのはキチガイ以外他ない 全てのAPIにパンは焼けませんって書かせる基地外w 文字列の痴漢は頼みもしないのに勝手にされたら邪魔だ テストもしないクズなのは確定なんだが
「仕様」かどうかが主語であるべきなのに、仕様かどうか「決まっている」というところを主語にして
続けていること自体がもはや技術者ではない >>520
>fopen()つまりCreateFile()
全然つまりじゃねー
Windowsではそういう環境変数よりもレジストリ使えってスタンスじゃないの C言語って極力余計なことはしないスタンスだから
環境変数の展開はやりたければ、自前でやったうえで fopen に渡せであって
展開動作を行なうようなのは printf のフォーマットのように 特記されてる
気がする >>526
でもレジストリに記録されているMSのデータって%1とかそういう系多いよね cout 前提に描かれてて
wcout 使うとおかしくなる レジストリのCLSIDのツリー見ると吐きそうになるんだけどどうにかならないのか プロセスにデバッガがアタッチできないようにしたい場合はどうすればいいのかな IsDebuggerPresentでも使ってアタッチされてたらプログラムを終了させる
カジュアルハック相手なら十分でしょ
本気でハックしてくる相手なら十分な対策は存在しないので考えるだけ無駄
Webアプリにするとか、攻撃者のテリトリーで秘密を実行しないことを検討しろ 多重のアタッチってできたんでしたっけ?
自前で用意しておいたデバッガプロセスに先にアタッチさせておくとか? それAPIHookでFALSE返されたら終わらない? 難読化も含めて ある程度攻撃者に対して面倒くさくさせることは出来ても
バイナリ渡した時点で無敵はない。。。 バッチファイルのコマンド文字列に含まれるマルチバイト文字が既定のコードページで解釈されることを保証するにはどうすればいい?
バッチファイルをパイプでつないだ別プロセスがSetConsoleOutoutCP()を呼び出すと、バッチファイルから呼ばれたコマンドで引数が文字化けしてしまうようだ SetConsoleOutputCP()に訂正。
hodeでSetConsoleOutputCP()が呼ばれると、foo.bat内のコマンドが正しく引数を受け取れない
foo.bat | hoge Windows 版 Ruby(MSYS2)では、端末の日本語入力でバグるので、あきらめた。
CP932, UTF16LE などか?
UTF-8 にも設定できるようだが、それでもバグる。
自分で環境変数RUBYOPT に、--encoding=UTF-8 を設定しているからかも知れないけど
結局、Windows をあきらめて、Linux を使う事にした
WSL2, Ubuntu 18.04 の端末では、バグらない。
たぶん、UTF-8 に固定されているのだろう >>548
情報をありがとう
foo.bat標準出力の受信先プログラムhogeでSetConsoleOutputCP()を呼び出すのを可能な限り遅らせることで対処することにします
batファイル全体が読み込まれてからバッチ処理されるのではなく一行ずつ解釈されていく副作用は以前にも経験したことがあります
バッチ実行中に、batファイルから一行を丸ごと削除したら、その行が呼ばれなかった WNDCLASSEX
↑明らかにセクハラ。発音するたびに気まずくなる。MSはセクハラ用語を廃止すべき。 先生「続きを読みなさい、551
551「はい、えーとワンドクラス…セ、セックス…
先生「ウィンドウクラスイーエックスな
みんな「クスクス… vc2017だとkernel32.libとかuser32.libとかリンクするファイルに書いておかないといけなかったけど
vc2019だと何も書かなくても勝手にリンクされてる気がするんだけど
気のせい?オプション変わった? 白黒でしかプリントしないアプリとか影響ありそう。
サクラエディタのソースコードCImageListMgr.cppの668行付近に以下のようなコメントがある。
// 単にCreateCompatibleDC(0)で取得したdcや
// スクリーンのDCに対してCreateCompatibleBitmapを
// 使うとモノクロBitmapになる. 1.昔がいい加減過ぎたので治すのは良いこと
放置はセキュリティホールになりかねない
2.MSがWin32APIを終わらせるための陰謀 そもそもスクリーンDCにプリンターDCをSelectObjectする意味が分からん
印刷(プレビュー)のときに使うの?
それなら普通、描画処理に出力先のDCを渡してスケーリングするだけじゃないの? 今時プリンタにはあんま印刷しないけどpdfには出力したりするから影響はありそうだね DC使うにせよ>557みたいなことしてて問題になるとは思えんけどな 自作アプリのPDF作成はプリンタDCに頼らずに自力でやってる わぁそれは凄い。是非GhostScript越えの
OSSとして公開してくれたまえ [名前を付けて保存]で.pdfが選択できるあのパターンか まさか、そんなWin32api全く関係ない
やり方で実装して専用スレで自慢したりしないでしょぅ
XPS経由だってスレ違いかと。
自慢するからにはバイナリーで直接生成していると見た。
公開早よう >>573
何を言ってるんだ?
> [名前を付けて保存]で.pdfが選択できるあのパターンか
が簡単にできるなら俺も知りたいぞw >>572
印刷の出力先をプリンタでなく「Microsoft Print to PDF」とかにするって普通にやらない?
古いOSならフリーソフトの「Cute PDF Writer」とか それはプリンタDCを使って印刷するんだべ
570でそれは否定されているぞ >>576
普通にやるけど
ワードも一太郎もドライバ型じゃないpdf出力機能あんじゃん ReadDirectoryChangesExWでroutine渡して非同期フォルダ監視してるんだけど、これって通知来るたびに一回一回登録し直さないといけないの?
通知 → 登録し直しの間は監視漏れが発生しうるって事だよね? どうやらDeleteFile関数はナイフのように危険な関数と見なされているらしい。使うのはためらうがいい。 >>580
完璧に監視したいならカーネルドライバ仕込むしかなさそうか 完璧かどうか忘れたが、登録し直しなんてやった記憶ないな 登録し直しなんてやった記憶無いし
しなくても通知は来ることは来るけど
ちゃんとしてても普通に取りこぼすことはあった気がする >>585>>586
それはSHChangeNotifyRegisterの話?
もしくはReadDirectoryChangesExWでもIO完了ポートで受け取る方式なら継続的になるとか?
完了ポートでの非同期IQはややこしそうだからとスルーしていたが >>587
585だけど昔のソース見たら専用スレッドで下みたいなことしてた。登録し直してるわ
OVERLAPPED ol;
ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
for (;;) {
bRet = ReadDirectoryChangesW( hDir, buffer, buffer_size, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME |FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_SIZE |FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_SECURITY
, &dwByte, &ol, NULL);
ol.hEvent を WaitForMultipleObjects で待つ
bRet = GetOverlappedResult(hDir, &ol, &dwByte, TRUE );
for (;;) {
pInfo = (FILE_NOTIFY_INFORMATION *)&buffer[i];
別スレッドの待ち行列に追加
if (pInfo->NextEntryOffset == 0)
break;
i += pInfo->NextEntryOffset;
}
} タッチスクリーンとして扱われる入力デバイスがあるのですが、これをマウスのように扱いたいです。
具体的に言うと、ブラウザ等のアプリ上でWM_POINTERDOWNが発生した時点でマウスの左クリックと同等の動きをさせ、POINTERDOWN以外のWM_POINTER系メッセージを握り潰したいです。
SetWindowsHookEx()で、起動中の各アプリケーションに対して自作dll内のフックプロシージャをインストールしたのですが、下記StackOverflowの投稿と同じ状態になって詰まっています。
https://stackoverflow.com/questions/21069643/is-it-possible-to-remove-touch-messages-wm-pointerdown-etc-that-an-applicatio
フックタイプにWH_CALLWNDPROCを指定すればメッセージの握り潰しや書き換えができるようなのですが、その場合どのようなウィンドウメッセージをフックすれば良いのでしょうか? このスレでいいのか判りませんが質問です。
WindowsのタブレットはUSBマウス等のポインティングデバイスを差さないとマウスカーソルが表示されないのですが、
APIか何かでマウスカーソルを表示させる方法ってありませんか?
タブレットでSendInputで自動操作させる時にマウスカーソルが表示されず、何が起こっているのか判らないので何とかしたいです。
kokomiteみたいなソフトも試しましたが、ログイン前とかでは使えないので他の方法がないか探しています。 SetProp(), GetProp() っていつごろからあるんだろう?
これらの関数の存在を最近まで知らなかった >>593
回答ありがとう
HWNDにユーザ定義構造体を紐づけて管理できるのはかなりありがたい。
今まで20年以上知らなかったのは、我ながら恥ずかしい。 SetProp/GetPropはstd::mapみたいに使えて便利だが、システムやアプリが無断で勝手に使う関係ないデータが交じる恐れがあるから注意。 >>594
WindowClass.cbClsExtra や WindowClass.cbWndExtra にポインタのサイズを登録しておいて、
::CreateWindow(..., this)
::SetWindowLong()/::SetWindowLongPtr()
::GetWindowLong()/::GetWindowLongPtr()
とかをやる手法は win3.1 からあったと記憶しています
>>593,592
https://docs.microsoft.com/en-us/windows/win32/winmsg/using-window-properties
を初めてみていますが、Window Properties とはどういう概念でしょうか?みたところ上記の api 群が扱うオブジェクトとは違うようですが >>596
はい。ご紹介いただいた関数は知ってましたが、
ユーザー定義データをひとつしか登録できないので、使うのを避けてました >>591
>マウスジグラー
こういう製品があるんですね。ご紹介ありがとうございます。
ただ、機能の割にお値段が結構するみたいなので、無線マウスのドングルでも繋いどけばよさそうですね。
仮想マウスドライバの作成も検討してみます。
ありがとうございました。 >>599
SetCursor、ShowCursorを試してみましたがだめなようです。
マウスカーソルがが表示されない状態の簡単な再現方法ですが、
Windows10が入った適当なデスクトップPCにマウス等を繋がずに起動するとこの状態になるようです。 GetTickCount()
東京五輪期間中の49日間、在宅勤務を求めた政府に「不吉」の声 - ライブドアニュース
https://news.livedoor.com/article/detail/20359990/ もともとテレワークだから関係ないけど
夏期休暇中にバリバリ旅行する予定は入れてるな
ハハハ 49.7日間で終わるのが嫌ならGetTickCount64()を使えばいい 今さらだがGetTickCountで四十九日という考え方をしたことないけど、覚え方としてはありか 95時代から何度もトラブルを起こしている
49日deathと名前が付くぐらいだし 次の設定でマウスカーソルが表示できました。
Windowsの設定 → 簡単操作 → マウス → マウスをキーパッドで操作する : オン
または下のレジストリ設定後、一度ログアウトし再度ログオンする。
rem マウスオン
reg add "HKCU\Control Panel\Accessibility\MouseKeys" /v Flags /t REG_SZ /d "159" /f
rem マウスオフ
reg add "HKCU\Control Panel\Accessibility\MouseKeys" /v Flags /t REG_SZ /d "158" /f
レジストリ設定の場合、一度ログアウトが必要なのが解せませんが、これで一応ソフトウェアでカーソルの表示まではできました。 なお、ログオフ前もマウスカーソルを表示させたい場合はHKU\.DEFAULTに設定すれば良いようです。
reg add "HKU\.DEFAULT\Control Panel\Accessibility\MouseKeys" /v Flags /t REG_SZ /d "159" /f
とりあえずこれで大丈夫かな? >>605
Vistaでいろいろ作り直されたせいで497日になったのが笑えた
当時2008R2動かしてたサーバが引っ掛かりまくったわ こんにちは。
C++ でSDIウィンドウを管理するためのラッパークラスを作っているのですが、
正直、継承クラスを作成してウィンドウをカスタマイズするたびに新しい
ウィンドウクラス名を指定する作業が面倒くさいです。当初は
string SDIWindow::get_wndclass_name() const {return typeid(*this).name();}
このような仮想関数を用意していたのですが、std::typeid::name() の返却値は実装依存で、
空文字すら返すことがあると聞き、ボツ案になりました。どうにかウィンドウクラス名を
自動生成したいのですが、妙案はありませんでしょうか。MFCなどのツールではどのように
名前を付けているのでしょう?よろしくお願いいたします。 >>609
自分でMFCヘッダーを探せばいいことを、わざわざ質問すべきではありません
質問を取り下げてください >>609
コンストラクタで__func__を使ってみたらどう? ご回答くださった方々、ありがとうございます。
__func__ これだ、と思ったのですが、いま使用しているコンパイラが相当古く、
この機能をサポートしていないようです。何かうまい方法がないかもう少し考えてみます。
>>612
自分もオブジェクトのアドレスを利用できないかと考えていたのですが、インスタンスごとに
アドレスが異なると困るのではと思い、保留していました。 コンストラクタの呼び出し位置で __FILE__と__LINE__を使った文字列をセットするとか >>614-615
ありがとうございます。
なるほど! __FILE__, __LINE__ の組み合わせは盲点でした。
これなら確かに、オブジェクトとウィンドウクラスを1対1で対応させることができますね。
少なくとも当座はこれでしのげます。
uid、guid 案もありがとうございます。
知識不足のため、勉強してから考えてみたいと思います。 ウインドウクラス名は文字列の他にATOMでも指定できる
ATOMはRegisterClass()が返す dllmainの最初の引数のHMODULEっていうかハンドルと同じ値を取得するwin32apiある?
ライブラリ作ってるけど、dllmain自体をライブラリに含めたくないから困ってる。
dllmainからHMODULEをライブラリに渡せ
みたいな変な規則も出来れば避けたい... GetModuleHandle(NULL)をキャストしる GetModuleHandleのNULLは大元の実行ファイルのパス。
そうじゃなくて.dllのパスが欲しい。
その際dllmainの第一引数を使わない形で欲しい。 んでリンカーでエントリーポイントを自前のにしつつ
コンパイラのスタートアップに渡す過程で hInst をくすねるしかないんじゃないの? 定義関数自身を渡しつつ、リファレンスカウンタを増やすのを回避する以下の形でいけるっぽい。
HMODULE GetCurrentModule()
{
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
HMODULE h = 0;
::GetModuleHandleEx(flags, reinterpret_cast<LPCTSTR>(GetCurrentModule), &h);
return h;
} そのライブラリを利用して
dll を記述するときは dll 自身を指して
アプリケーションを記述するときは実行ファイル自身を指すと
(GetModuleHandle() は、常に実行ファイルを指す) >>618
DLLは、アプリと同じ仮想アドレス空間を共有しており、HMODULEの値は、
DLLの PE イメージの先頭アドレスだと聞いている。
そして、DLLは単なる関数の集まりに過ぎないので、「現在のDLL」という
概念が存在しない。
dllmain が呼び出されて、OSに戻るまでの間の時間、現在どの dllmain が呼び出されているか、
という情報なら OSはどこかに持っているはずではあるが。
なお、DLLの関数群は、通常、dllmain が呼び出されている間以外に使うことが原則。 dllは現在実行中のdllという概念はあるのでは。
あるからこそ、c++/cliでは簡単かつ確実なものとして提供されてるわけで。 あと、現在実行中のニーモニックのアドレスより若い直近アドレスに位置するモジュールのエントリーアドレスであればそれが求めるものだし。
620は関数定義が属するdllのハンドルを得る関数になってるから、実用上問題なく機能するよね。 そもそもDllMainのHMODULEを使わないって縛りプレイでのお話でおすし >>626
そういう概念は無い。
dllmain() は、DLL が最初にロードされたとき、スレッドが開始するとき、
及び、それらの終了する時に呼び出されるエントリ関数に過ぎない。 >>618
> ライブラリ作ってるけど、dllmain自体をライブラリに含めたくないから困ってる。
そういのだとリンカーとかの話で、APIでどーとかってのとはまた違うような >>629
[補足]
「現在ロード中で使用中の DLL」
という概念ならある。 >>621
[補足2]
2つ以上のDLLを使用中の場合は、その内のどのDLLのどの関数が今まさに「実行中」か
どうかは、OSレベルでは管理されてないという意味で言っている。 >>632
>>631 へのアンカーミスだった。スマン。 いや実行中のステップがどのdllかという概念はあるよ。
あるからデバッガでも今の瞬間実行中のステップがどの.dllのどのアドレスかまでわかってるわけで。 各々dllのベースアドレスは管理してるんだから、管理してるだろ。
管理してるかはdllは解放されるんだろ?
ベースアドレスからファイル名が辿れるから何のファイルか解るようになってるんやないか。
だからぶっ飛ぶとシステムログに飛んだdll名が明記されるやないか。 GetModuleHandleExの仕様をみればOSの管理下にあるのわかるじゃん。
2番目の引数には。モジュールのパスでもよいが、
「モジュール内の任意のアドレス」でもいいわけ。
即ち今プログラムでましに実行中位置であるEIPレジスタやRIPレジスタの値から
dllなりexeなりのハンドルがとれると書いてあるわけで。
もちろんハンドルがとれるからファイルのパスもわかる。
管理下になかったらどうやって取れるんだってのw >>637
> 各々dllのベースアドレスは管理してるんだから、管理してるだろ。
それは
>> 「現在ロード中で使用中の DLL」
な でも結局CPUの命令アドレスからdll名を求められるから、
今CPUが実行中のdllやexeはOSが管理してるし、それ用のwin32apiも提供されている、であってるやん。 どこを実行中かをOSが管理してるなら、暴走なんてせんわな
デバッガはbreakしたらやってるだけ >>642
dllを実行中かなんて管理してないぞ
単にスタックの戻りアドレスから.dll検索してログに書き込んでるだけ プロセス単位でexeやdllのアドレスを簡易的に言えば配列のように保持してて
あとはEIPが配列のインデックスであるかのように実行時に動くだけだから管理できてるじゃん。
indexに幅があるってだけでしょ。 >>645
OSはEIPを管理なんてしてないぞ
そもそもぶっ飛んだ時に関数レベルのスタックトレースができるからと言ってOSがどの関数を実行してるかを管理してるとでも言うのか? いったいいつ関数の話になったんだ。
EIPからいつでもモジュールを辿れる形でプロセス情報を保持してるから管理されてると言ってるんだが。
プロセス情報を保持してないなら管理してないと言えるが。 管理されてるを監視してるに勝手に脳内で置き換えてないやろな? 管理されているというより、EIPアドレスから逆算しているという感じだね。
実行中のマシン語の命令のアドレスが分かれば、リンク時のマップファイルのような
情報があれば、どの関数の中のマシン語かまで分かるから。 どの人がどこにいるかを国は普段は追跡してないけど、科学捜査すればどこにいるか
分かることが多いと言う意味で、「管理はしてなくても見抜くことは出来る」
のと同様の事。 >>649
各DLLがロードされている場所のアドレス範囲とEIPさえあれば、そりゃ、どのDLL
にいるかは分かるけれど、それは管理とは言わないと思うな。
マシン語で、jmp アドレス、call アドレス で、1クロックですぐに EIP = アドレス
になるが、それをOSはいちいち追跡も管理も全くしていない。だから、
現在どのDLLの関数を実行中かをOSは情報としては持ってない。
ところが、EIPの値からどのDLLの中を実行中かを「逆算」することが可能と言うだけ。 プログラミングの世界で「管理」というのは、
struct SomeInfo {
int curDllIndex; // 現在実行中のDLLのインデックス番号(0-)
};
のようなデータ構造があり、idx1 という番号の DLL の中の関数を呼び出すときに、
プログラムで curDllIndex = idx1 にちゃんと書き込む、ということをイメージする。
このような意味での書き込みは行われてない。 OSに管理されているのであれば、idx1 番の DLLから、main モジュールの関数 f()が
コールバックされたような場合でも、どのDLLから呼び出されたかまで分かるはずだが、
現実にはEIPは、f()の中をポイントしているから EIP だけからは、idx1 を逆算する
ことは不可能。
デバッガが出来てしまうのは、デバッグしやすい様にコンパイラが
「スタックフレーム」という構造が出来るようなコードをわざと作っているから。
その構造によれば、スタックとEBPの値で呼び出しもとの関数の履歴を全て辿って
いける。
しかしこれは、OSが管理しているのではなく、デバッグ版ではそのようなコードを
コンパイラが生成しているからに過ぎない。
リリース版では効率向上のためスタックフレームが省略されることもあり、その
場合は呼び出しもとの関数が辿れなくなるので idx1 という番号を算出することは
原則的には出来なくなる。 >>655
[補足]
スタックフレームは、「ユーザーランド」のアドレス空間に構成された構造で、
OSが「管理」する「システムランド」のアドレス空間にはない。
前者はプログラムに誤りが有ると壊れることがあるし、コンパイラのオプション次第
で省略されることもあるから、いつでも存在するわけでも無いし、いつでも正しい
訳でもない。
その意味で、OSの管理する構造ではない。 Tool Help Library ぐらいは調べて
から書きたまえ。 >>657
オタクが調べて書けばいいんじゃね?
何を書きたいのか知らんけどw 「管理」の定義が独り歩きしているがもともとは>>629-632だろ?
その意味では「管理」されているでいいんじゃね? >>659
どこに書いてあるのかレス番示して引用してみ
どうせ逃げるなら速い目に頼むw >>660
それに対する>>635がおかしいって言われてるんだろ 「Hacking: 美しき策謀 」ぐらいは読んでこいよ 本当に管理されていると言うのなら、別のlibで定義されている
HMODULE get_this_dll_module();
という関数によって、あらゆるDLLのHMODULEを取得できるようになるはずで
あるが、この関数は、スタックフレームを前提にしない限りは基本的に
作ることが出来ない。なぜなら
void get_this_dll_module() {
// ここの EIP の値は、呼び出しもとの DLL のものとは違っている。
}
からである。 >>665
誤: void get_this_dll_module()
正: HMODULE get_this_dll_module()
EIPのアドレスは、簡単に変わりうるものなのだ。 >>667
現在の関数からその関数が格納されているDLLのパスまで取得できる情報があることを
OSが管理していると呼ぶかどうかで
外野がうんこの投げ合いをしている 無駄な議論ではなく、質問者が、現在実行中の関数の所属する
DLLを正確に取得する方法があると思い込んでいた可能性があるので
大事な指摘だった可能性がある。
結論から言えば、安定してそれを取得する方法は無い。 get_this_dll_moduleてなんなんってぐぐったら
このスレが引っかかってわろた
脳内の関数だったか 未解決のせいで盛り上がってたのかと思ったら>>622で解決してたのか 「D:\aaaa\bbbb」などの、ファイルやフォルダのパス名から、
そこがCDやDVDなどの光学ドライブかを判定する仕組みはありますか? 途中送信ごめん
全ドライブ文字と種類がわかるから
後は比較するオレオレ関数作る感じ >>678
ありがとうございます。
GetDriveTypeは、"D:\"の3文字の部分しか渡せないようですが、
PathGetDriveNumberでも使えば、"D:\"の部分だけを作れそうですね。 リッチエディットに複数行の文字列をプログラムから定期的に送って全内容を更新するプログラムを作成しています。
更新中は垂直スクロールバーで任意の行に移動できるようにしています。
コードは下記です。
LRESULT Line = SendMessage( hEdit, EM_GETFIRSTVISIBLELINE, 0, 0 ); // 現在の表示行を控えておく
SendMessage( hEdit, WM_SETREDRAW, FALSE, 0 ); // 文字列更新中の状態が露呈しないよう再描画を抑制する
SetWindowText( hEdit, str ); // 全文字列更新
SendMessage( hEdit, EM_LINESCROLL, 0, -INT_MAX ); // 表示行を一番上に移動する
SendMessage( hEdit, EM_LINESCROLL, 0, Line ); // 表示行を、控えておいた位置に移動する
SendMessage( hEdit, WM_SETREDRAW, TRUE, 0 ); // 再描画再開
InvalidateRect( hEdit, NULL, FALSE ); // 表示を促す
これで、ある程度までの行数の文字列であれば、意図通りの挙動となるのですが、
行数が多くなってくると、動かしていたスクロールバーが一瞬一番下まで下がってから
元の位置に戻るという現象が文字列更新の度に起こります。
ただ、リッチエディット内の表示位置は、動かしていたスクロールバー位置に対応する位置のままで、
スクロールバーが一瞬一番下がる動きとは連動しません。
一体何が起こっており、どのようにすれば回避できそうでしょうか? >>681
改行文字(\n)だけの80行くらいでも発生しました。
そして>>680の内容に訂正があります。
>動かしていたスクロールバーが一瞬一番下まで下がってから
は、一番下までは下がっていませんでした。
また、下がったときはバーが長くなっており、
あたかも行数が少なくなったかのよう(エディット内の表示は意図通り)な挙動です。
さらに、以下のような性質も分かりました。
・スクロールバー位置が一番上のときは一瞬下がる症状が発生しない
・スクロールバー位置が一定より下になると一瞬下がる症状が発生しない
・この位置は全体行数とリッチエディットの縦幅との関係によって変わり、
スクロールバーの長さが全体の大半を占める場合はどの位置でも発症しなくなる >>682
キャレットが画面外にあるか画面内にあるかで挙動は変わったりする? 一口にリッチエディットっていってもバージョンが4種類くらいあって
それぞれ微妙に動作が違ったような気がする >>683
文字列更新前にキャレットが画面内にあるか画面外にあるかで挙動に変化ありませんでした。
>>684
リッチエディットのバージョンはv2.0(UNICODE)です。 特定プロセス(PID)のアドレス空間の情報を取得するAPIはありますか? スクロールバーの描画も同時に禁止するとか
スクロール範囲の最大値も強制的に変更してから描画再開するとか >>685
キャレットが画面内でも外でも
おかしな症状が発生するかどうかは>>682の条件って事? >>687
スクロールバーのハンドルを取得する方法が分からなかったので、
テキスト&スクロールバー位置更新時、ダイアログ全体の再描画を抑制してみましたが、
再描画がかかるタイミングでやはりスクロールバーが一瞬動きます。
スクロール範囲の最大値もテキスト更新前に控えておいた数値を、テキスト更新後に設定しましたが変わらずでした。
>>685
はい、>>682の条件です。
進展がありました。
SetWindowText()でテキスト更新をしていた部分を
SendMessage( hEdit, EM_SETSEL, 0, -1 );
SendMessage( hEdit, EM_REPLACESEL, FALSE, ( LPARAM )str );
と置き換えたところ、
スクロールバーを動かしても、その後、一瞬下に動くといったことがなくなり、
期待通りその場に留まり続けてくれました!
しかし、ダイアログのフォーカスを外した後、再度フォーカスを得ると、一番下に飛んでしまいます・・・。
惜しい・・・。
フォーカス取得の際、スクロールバー位置が更新されるものと思われますので、
そのときのウインドウメッセージを捕えて、テキスト更新時と同様にスクロールバー位置を制御すればいけるかもです。 >SendMessage( hEdit, EM_LINESCROLL, 0, -INT_MAX ); // 表示行を一番上に移動する
>SendMessage( hEdit, EM_LINESCROLL, 0, Line ); // 表示行を、控えておいた位置に移動する
これで振動してるような気もする
フォント高さ x 行数 と クライアント領域の高さが不一致な状態で
SetWindowText() で更新したとき、クライアント領域内の先頭行側が欠けて 最終行側がきっちり見えてるんだけど
上の2行の変わりに
SendMessage( hEdit, EM_LINESCROLL, 0, 0);
を投げると先頭行がきっちり収まる位置にきて、スクロールバーがピコピコすることもない雰囲気 >>689
ダイアログカヨ
WM_ACTIVATEが悪さしてるとかない? WM_VSCROLL.SB_TOP使った方がいいんじゃね? >>680
>SendMessage( hEdit, WM_SETREDRAW, FALSE, 0 ); // 文字列更新中の状態が露呈しないよう再描画を抑制する
↑は、RichEditControl のメッセージではなく、Win32のWindow一般のものらしい。
但し、MSDNには、ListBoxで複数のアイテムを追加するときに便利だと書いてある。
質問者の実験を聞く限り、RichEditControlにのみこのメッセージを送っただけでは、
そこにくっついているスクロールバーに対しては効果が無いようだ。 Rich Edit Control を作成する時のスタイルに
WS_VSCROLL
を付け、
ES_DISABLENOSCROLL
を付け、
ES_AUTOVSCROLL
を外すと縦スクロールバーが出るが、勝手に制御されにくくなるかも。 SendMessage( hEdit, WM_SETREDRAW, FALSE, 0 );
は効果は有るにはあるが、アプリ側が自らスクロールバーを制御するようなメッセージを
Rich Edit Control に送った場合、↑の設定が無視されて、スクロールバーの描画が
起きてしまっている可能性がある。なので、
>SendMessage( hEdit, EM_LINESCROLL, 0, -INT_MAX ); // 表示行を一番上に移動する
>SendMessage( hEdit, EM_LINESCROLL, 0, Line ); // 表示行を、控えておいた位置に移動する
の部分、上の行を省いて、下の行だけにするとちらつかなくなる可能性が高い。
また、上の行の役割の代わりとして、カーソルの位置はスクロールの位置とは別に制御すると良いはず。 >>690
EM_LINESCROLLは現在位置からの移動を指示するので、
SendMessage( hEdit, EM_LINESCROLL, 0, 0);
だと何も作用がありませんね。
>>691
>>689の処理ですが、WM_ACTIVATE後、次のテキスト更新までの間に、スクロールバーが一番下に移動する動きが確認できました。
>>692
SB_TOPで一番上に戻しても症状は同じでした。
>>693
再描画抑制をしないと、テキスト更新の際の過渡的な状態が露呈し、スクロールバーも一瞬動くのが見えたりするのですが、
再描画抑制により、これらが露呈しなくなるので、スクロールバーにも効果があるようです。
>>694
試してみましたが症状変わらずでした。
>>695
英語が苦手で完全には理解できないのですが、
再描画抑制解除後のWM_PAINTあたりでスクロールバー位置が更新され動いてしまうということがあり得そうですね。
>>696
上記の通り、
EM_LINESCROLLは現在位置からの移動を指示するので、
SendMessage( hEdit, EM_LINESCROLL, 0, Line );
だと下に動き続けてしまいます。
試しにリッチじゃないエディットボックス(MultiLine有効)に置き換えたところ、すんなりいきました。
前にも試したことがあったんですが、リッチエディットが\nだけで改行されるのに対し、
エディットボックスでは改行されなかったのでダメだと思っていました。
本日、エディットボックスの場合は\r\nで改行されることを知り、これでうまくいきました。
\rが増える分、更新(転送)する文字量が増えてしまいますし、その他、リッチエディットとは異なり、
・ReadOnlyだと背景がグレーになる(審美的にはリッチエディットのような白が好ましい)
・表示矩形内に文字が収まっていてもスクロールバーの枠が表示される
・表示がたまにチラツく
といった気になる点があるのですが、不安定なスクロールバーに比べたら許容範囲です。
多数のご助言をいただき、ありがとうございました。 どうでもいいけどWin32とかの文字列の型名わかりずらすぎて嫌がらせとしか思えない
なんだよLPCTSTRってconst wchar_t*でいいだろ スカラ値へのポインタではなく配列先頭アドレスですよという意図は一応あるのかもしれない UNICODE マクロが定義されていればそれはそう Tがつく奴はUNICODEの定義の有無でwchar_tかcharに変わるから >>701
そもそも全部wchar_tでいいって事なら
TじゃなくてWでいい UNICODE対応とはいわばUTF8に対応していると思っている僕がかつて居ました いまどき -D_UNICODE せんやつはおらんよな?よな? >>706
>いまどき -D_UNICODE せんやつはおらんよな?よな?
自分はここしばらくWindowsのプログラムから離れてるんで、思い違いしてるかもしれんが・・・
いまどきはWindows10のワールドワイド言語サポートを使ってアプリ内部・外部入出力ともUTF-8にするんじゃないか? _UNICODEはWin32APIがUTF-16版かどうかの話なんでアプリは好きにやりゃええねん >>707
VC付属のCライブラリがUTF-8に完全対応してない
ファイルオープンで積む
VCの対話デバッガも変数のUTF-8テキストビューに対応してない ビジネスが破綻する大半の原因は、 ”ビジネスを始める人の大半が、真の意味での
「起業家」ではなく、 起業したい、という熱に浮かれた「職人」として働いているに過ぎない。”
という事実にあります。
「職人」によって運営されているビジネスは、ビジネスが働くのではなく、彼ら自身が毎日働くこと
によって、成り立っています。
彼らは毎日、自分がやり方を知っている仕事を一生懸命にこなしていますが、「起業家」としての
視点が無いために、成長に限界が生まれます。
そして、生計を立てるために、彼ら自身がずっと働き続けないとならないのです。
誰もが必ず陥る罠
私が見ている限り、起業熱にうなされる人たちは、必ずと言ってもよいほど誤った
「仮定」を置いてしまうようだ。実は、のちに彼らが苦難の道を歩むことになるのは、
この、「仮定」が致命的に間違っているからなのである
致命的な仮定とは・・・「事業の中心となる専門的な能力があれば、事業を経営する能力は
十分に備わっている」ということである
私がこの仮定を致命的だと書いたのは、この仮定が間違っているからにほかならない
事業の中で専門的な仕事をこなすことと、その能力を生かして事業を経営することは
全く別の問題である。高い専門能力を持つ人にとって、独立は他人の為に働くという苦痛から
解放されるということを意味していた。それにもかかわらず、前提となる「仮定」が致命的とも
いえるほど間違えているために、彼らは自由になるどころか、自分が始めた事業に苦しめ
られるようになってしまうのである
マイケルEガーバー「はじめの一歩を踏み出そう」P28~29 Windows用のMFC製のアプリをシェアウェアとして公開するのに、
Vector以外に良いものは無い?
Vectorは作者登録の手順がとてもメンドクサイ。
写真を送ったりとか、作者にばかりプライバシーや個人情報を負担させる仕組み。 >>712
>作者にばかりプライバシーや個人情報を負担させる仕組み。
ソフトウェア等のダウンロード販売は、
特定商取引法に基づいて住所や氏名(法人名)等の公開が必要
>Vector以外に良いものは無い?
自分のHPにアップしてReadMeに振込先等書いとけば? >>715
Vectorのシェアレジって、作者の住所が公開されるんだっけ?
それは困るな。 こういうのとかは?
ttps://blog.okazuki.jp/entry/2018/10/04/160349 >>717
マイクロソフトストアに登録するためにMFCを変換しなくてはいけないらしくて
そのやり方がめんどうくさそう。
どうすればいいのかよく分からない。 インストーラー作りに2ヶ月くらいかかりそう。
なんのためにそんな必要が。 MFCメインアプリを起動するためだけのUWPランチャアプリでも登録すればワンチャン? ヤフオクでデータやパスワードを売ることも出来るらしいけど、
一回登録したら100人でも1,000人でも売れるようにすることは出来ないのかな?
そもそも、1000人分を「商品」として一度に登録できるのだろうか? Windows 11のストアで配布する
あれって何でも配布できるようになるんだっけ?? 以下のようにテキストログファイル名を変更してそれを読み出す処理があるのですが
fopenでNULLが返ってくる事があり、GetLastErrorで得られるエラーコードは0x00000020で
「プロセスはファイルにアクセスできません。別のプロセスが使用中です。」
となります
自アプリだけが吐き出して使うログファイルでプロセスの多重起動もしておらずシングルスレッドで、
そもそもMoveFileで成功が返ってきているのに直後のfopenでエラーになる原因が見当付きません
unlink(dst_path);
if (MoveFile(path, dst_path)) {
fp = fopen(dst_path, "rt");
苦し紛れにMoveFileの部分を
if (rename(path, dst_path) == 0 && PathFileExists(dst_path)) {
とやってみたこともありますが、やはりfopenでエラーになることがあります
毎日10時間以上稼働していて今年累計で13回ほどのエラーで低確率すぎるのと対策が思い付かなくて困っています
原因と可能性について助言頂けませんでしょうか >>724
ウィンドウズは、裏でシェルの変更通知やウィルススキャンやフックなどが動いてたりするんだよね。
それでファイルの確実な処理をしたいと言うことなら、処理を見直す必要がある。MoveFileを一つの処理と思ってるなら間違いだ。実際にはコピーした後で削除している。
【現在の処理】
Dを削除。
SをDに移動(実際はSをDにコピーしてSを削除)。
Dを読み込み。
【提案】
SをDに上書きコピー(CopyFile/CopyFileEx)。
Sを読み込む。
Sを削除。 >>725
>実際にはコピーした後で削除している。
それは異なるドライブの場合だろ?
同じドライブの場合はファイルシステムの書き換えだけのはずだろ >>725-726
レスありがとうございます
質問が長くなったので要点を絞り込んだつもりでしたが、もう少し追記させていただきます
dst_pathはpathの拡張子のみを変更したものですので、同じドライブ・フォルダになります
また、MoveFileの仕組みは仰るような仕組みで理解しているつもりですが、renameでも解決しないのが理解に苦しむところです
(といってもrenameの実装がどうなっているのか知らないのですが)
この処理で行っていることは、テキストログ中の不要な行を削除したいということで、
【現在の処理】
Dを削除。
SをDに移動(実際はSをDにコピーしてSを削除)。
Dを読み込みながら、Sに新規書き込み(削除したい行を読み捨てながら)。
という単純なことを行っていますのでご提案そのままではだめですが
【修正案】
Sを読み込みながら、Dに新規書き込み(削除したい行を読み捨てながら)。
Sを削除。
DをSにリネーム(MoveFile/rename)。
が思い付くのですが、そうするとSを書き込んでいるところ(全く別の場所ですが)で
もしかしてエラーが出るようになるのではという不安があります
いっそのことMoveFileの代わりになるものを自分で作ることも思い浮かびますが、
そもそも論として今回のような処理でここまでするものなのか?
という疑問と疑心暗鬼に陥っています 原因についてはわかりませんが。。。
MoveFile()代替として、ハンドル開いた状態でファイル名を変更する場合にはSetFileInformationByHandle()を使用する。
HANDLE h =CreateFileW(srcfilename, GENERIC_READ| GENERIC_WRITE| DELETE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
size_t fri_size =sizeof(FILE_RENAME_INFO)+(wcslen(dstfilename)+1)*sizeof(wchar_t);
FILE_RENAME_INFO *fri =(FILE_RENAME_INFO *)malloc(fri_size); memset(fri, 0, fri_size);
wcscpy(fri->FileName, dstfilename);
fri->ReplaceIfExists =TRUE;
fri->FileNameLength =(DWORD)wcslen(dstfilename);
fri->RootDirectory =NULL;
BOOL res =SetFileInformationByHandle(h, FileRenameInfo, fri, (DWORD)fri_size);
free(fri);
CloseHandle(h); >>724
fopenでのエラーを調べるならGetLastErrorじゃなくてerrnoじゃないかな? >>724
カーネル内でのリソース開放は即座に行われるとは限らない。
お触りしたプロセスがいなくなった後でもカーネルの中で残ることがある。
この場合は成功するまでfopen()するしかないね。 皆さんありがとうございます
>>728
対象ファイルがテキストファイルで一行ずつの処理のため、CreateFile系では
fgets系のAPIがないのでそこまで自作する必要がある点で最終手段として取っておきたいと思います
>>729
内部でWin32APIを叩いているイメージがありましたが、確かに言われてみればerrnoを使うべきですね
そのようにしてみます >>730
本件とは別件で新たな質問になってしまいますが、
プロセスAでファイルAをunlinkで削除
WM_APPを別プロセスBにPostMessageで通知
プロセスBでファイルAを再作成(プロセスBが起動していなくても、起動時にファイルAが無ければ再作成)
という箇所があるのですが、要するにキャッシュファイル的なものを削除して別プロセスで再作成を指示するようなことをしています
ここも稀に(?)再作成で失敗することがあるので気になっていました
Windowsプログラミングにおいて、ファイルの削除や移動についてはその後ウェイトを挟むか、
ファイルの作成でエラーが出たらリトライを入れるというのは常識的なものなのでしょうか? >>732
常識って人それぞれだからなあ...
エラー終了して使用者に丸投げするか、どこまでリトライするか、
ウエイトするのかリトライするのかはプログラムの次第だし...
今回の件のように、直前に誰かがお触りしてるのが
確実なのであれば、リトライするかウエイト入れるのが
確実だと思うよ。 >>731
CreateFile したハンドルを FILE * に変換したら fgets 使えるが >>732
>Windowsプログラミングにおいて、ファイルの削除や移動についてはその後ウェイトを挟むか、
>ファイルの作成でエラーが出たらリトライを入れるというのは常識的なものなのでしょうか?
根本的な思い違いをしているに一票 >>736
>>724がfcloseしていないというならそもそもfopenしただけとも言えるわけで説明のために以降は省いているってわかると思うんだが
そもそもが閉じ忘れならMoveFileも失敗するだろう >>737
せやな
_osfhandleとかfdopenをキーワードにggr そこまでせんでもcreatefileしたハンドルで移動してから一旦閉じてfopenでよくね? >>741
今回の問題は、いったん閉じてもカーネルが握ってるのでfopen()できないって話で >>743
だからMoveFileを代替しても同じやんって話で 論理的に考えれば「カーネル」が
握るわけ無いだろう。
ゴルフか麻雀でもしているののか ロクに質問読まずにというか理解せずにレスしてる馬鹿は何なの >>732
環境依存なことを考えて戻り値確認するのは別にWindowsに限らないし、戻り値が正常でも外部デバイス相手だとドライバ次第なこともある
別件で、組み込みWindowsでユーザがアプリが正常終了してすぐに電源コード引っこ抜くから
キャッシュがHDDに書き込まれずに消えるって事例はあったな >>749
NAS関係でOK出ているのに書き込まれて
いないってのはあったな LoadLibraryとかGetProcAddressしたものは
必ずFreeLibraryしないといけませんか?
自分のプロセスが必ず終了するときにFreeLibraryせずに放置しても勝手に解放される? >>75
されるわけないだろ
OSがナイナイしてくれるだけ >>751
プロセスごと始末してくれるから放置で構わん やって来ました
メッセージボックスで「計算結果はXX」って表示したくて
1 LPCWSTR func() {LPCWSTR a = L"//計算結果の値"; return a;} //計算結果を文字列にして返す関数
2 //以下WinMain()内
3 LPCWSTR a = L"計算結果は";
4 LPCWSTR b = func();
5 LPCWSTR c = 文字列を連結する関数(a, b); //StringCchCatW(), lstrcatW()などを試したがだめだった
6 MessageBoxW(hWnd, c, L"タイトルバー", MB_OK);
と書いたが動かなかった・・・
まず、1行目の「L"//計算結果の値"」に計算結果の変数を入れる方法がわからない
そして、5行目のLPCWSTR型の文字列を連結する方法がわからなからない
一日の大半がエラーとのにらめっこに費やされて辛い・・・
頼む、手伝ってくれさい >>756
Win32APIではなくC言語の文字列とポインタの違いを勉強するところからやり直し >>756
1 void func(CString &str) { str = "計算結果の値" } //計算結果を参照型引数の str に返す関数
2 //以下WinMain()内
3 CString str1 = "計算結果は";
4 CString strKekka;
5 func( strKekka ); // strKekka に計算結果の文字列が入って返って来る。
6 CString str2 = str1 + strKekka;
7 str2 を wide 文字列に直して、wpszText に入れる。 // ここはやり方を調べる。
8 MessageBoxW(hWnd, wpszText, L"タイトルバー", MB_OK); >>756
自分がどう書いたのかソースそのまま出して 普通にwstringベースで作れ。
win32のwchar_t*型渡すところで、data()やc_str()使え。
std::to_wstring で数値などなどメジャーな数値型はwstringになる。
最初はwin32の型に代替名つけまくりな文化は
一体なんの型だよって感じで戸惑うわな。 >>762
以下の関数を使えば、7 は、
wchar_t *wpszText = ConvertAcpMbcsToUtf16(str2);
でいける。
wchar_t *ConvertAcpMbcsToUtf16( const char *pszStr )
{
// ワイド文字列(UTF16, unicode) へ変換後の文字列長を得る
int lenUnicode = MultiByteToWideChar( CP_THREAD_ACP, 0, pszStr, -1, NULL, 0 );
// 必要な分だけ ワイド文字列(UTF16, unicode) のバッファを確保
wchar_t *pbufUnicode = new wchar_t [lenUnicode];
if ( pbufUnicode == NULL ) {
return NULL;
}
// デフォルトコードページ(ShiftJISなど) から ワイド文字列(UTF16, unicode) へ変換する :
MultiByteToWideChar( CP_THREAD_ACP, 0, pszStr, -1, pbufUnicode, lenUnicode );
return pbufUnicode; >>765
訂正:
1. は代入文の最後にセミコロンが抜けていたので正しくはこう :
void func(CString &str) { str = "計算結果の値"; } おっと、最後、MessageBoxW ではなく、MessageBoxA を使っていれば、
7や >>765 の工程は不要で、
MessageBoxA(hWnd, str2, "タイトルバー", MB_OK);
だけでいける。 なのでまとめると以下のようになる :
void func(CString &str) { str = "計算結果の値"; }
// 以下WinMain()内
CString strKekka;
func( strKekka ); // strKekka に計算結果の文字列が入って返って来る。
CString str2 = CString("計算結果は") + strKekka;
MessageBoxA(hWnd, str2, "タイトルバー", MB_OK); 連結はstrcatかsprintf("%s%s", s1, s2 )のTCHAR(wchar_t)版でいけるやろ
あとLPCWSTRはポインタなので、ちゃんと割り当てしてなくて未初期化のままとかないだろうな? LPCWSTRのCはCONST(定数)という意味だから、変更できない。WはWide、つまりUTF-16.
Win32をやる前にC言語の文字列処理をマスターしてくれ。
wsprintfは時代遅れ。バッファオーバーフローを避けるため、バッファサイズ指定できる<strsafe.h>のStringCch...関数群を推奨。 ポインタ変数は実体を持たない。文字列扱うにはバッファが必要。動的にバッファを確保して楽したいなら、標準C++のstd::wstringか、MFC/WTLのCStringWを使う。
ただし、std::wstringを使う場合でC文字列が欲しい場合はc_str()メソッドを使う必要がある。下手な型キャストはケガのもと。 WindowsでC/C++を学ぼうとすると、文字列の扱いは混乱するだろうね
OSを特定しない教科書に載ってるようなやり方もできるから心配するな
一応の結果の表示をできるようになったら、とりあえずその方法だけ使って次に進んで、一通り理解したらまた文字列処理に戻ってくるといいんじゃないかな ぎゃー
教えてくれたのに遅れてすまん
今からエディター起動する 付き合ってくれた人が多くて感謝!
上のコードで実験しながら知識の掘り下げも含めて少し調べてみる
ありがとうな
いつか立派なプログラマーになってこのスレで恩返しするわ(泣ける)
>>774
文字列の扱いがここまで面倒だとは思ってなかった
Windows APIの関数に適当に投げ込むだけだと思ってた
>>776
入門書は読んだだけで実作は先週始めた
(これ以上は理解が進まないので実作をすることにした)
まだ知識が実践で使えるように修正されてない状態
まあ知識もないんだが 先が思いやられるな
特にWin32APIにこだわる理由が無いならC#でやることをおすすめする 特殊な理由でもない限りネイティブc/c++なんて使わんでいいよ Cだと、こんな感じかな
- - - - - - - - - - - - - - - -
LPCTSTR a;
int b;
TCHAR c[20];
a = TEXT("計算結果は");
b = 2;
wsprintf(c, TEXT("%s%d"), a,b);
MessageBox(NULL, c, TEXT("タイトルバー"), MB_OK); なんでせっかくTCHAR使っててwsprintfやねん MBCSかUNICODE決め打ちならいらない
LPCTSTR,TCHARも同じ >>783
#ifdef UNICODE
#define wsprintf wsprintfW
#else
#define wsprintf wsprintfA sprintf/swprintfはC標準。
wsprintfはWin32。
これはテストに出ないぞ! >>789
Win32apiのスレなので、それ以外の答えを
書いた奴全員アウトあるね >>786
TCHARはワイドとマルチバイトの両方なんだからwprintf決め打ちじゃなくて_tprintf >>782
これからWin32APIを理解し始めようと考えている人には、そうゆう疑問を持てるレベルにまで頑張って到達してほしいな、という思いでマクロ表記にしてみたよ。
実用上、必要か不要か・・・で言えば場合によるんだろうけど。
現時点でWin32API が内部で ANSI と UNICODE を明確に区別しているので、作法として気にする必要はあると思われます >>792
なんでだよw
wprintfはWCHAR _T系の関数マクロは<tchar.h>で定義されていて、主にC実行時関数を振り分ける。これらはAnsi/Wideを振り分けるTEXT系とは別に分離された機構になっている。 >>794
wprintfはC標準のワイド関数。
wsprintfはWin32関数でA/W版がある。
一文字違いに注意。 UNICODEマクロでA/Wの振り分け。
頭に下線のついた_UNICODEマクロで_T系の振り分けができる。
これらはVisual Studioで適切にソリューション/プロジェクトの設定を行えば自動で定義される。
GCCやclangでは-municode をコンパイルオプションに追加する。
ただし、ユニコードプロジェクトではWinMainはwWinMainに切り替わるので注意しよう。 ユニコードプロジェクトにせず、代わりにUNCODEマクロと_UNCODEマクロを定義済みにするというやり方もある。こちらはCMakeでよく使う。 ユニコードプロジェクトではないときにUnicode のコマンドラインを取得したい場合は、GetCommandLineWと
CommandLineToArgvWと
LocalFree を使う。 ミッキマウスミッキマウスミッキミッキマウス
天安門事件
旭日旗☀ ,>>798
まぁ今となってはWindowsのUTF16LEはUNCO(ウンコ)なコードだったな
2バイト固定で1文字ってのは、簡易な多言語対応とstrlen系の文字数計算に楽だったんだろうけどそれだけだろ サロゲートペアに対応したので、その文字数計算も単純にできなくなってしまった。
文字数計算がややこしいのはUTF-8もそうなので、UTF16〜が全然ダメということではないが。
開発面では、将来的に UTF-16(IVS)が必要になってくると、UTF8でいいじゃん、ということになって。
Visual stduio のデフォルトが再度ANSI(UTF-8)に戻る可能性はある。
長い目でWin32APIを見るなら、ANSIアプリの構築方法も忘れないでおく必要はありそうだ アラビア語かなんか知らんが、サロゲートペアの問題ではなく、さらに
UTF32 では 2 文字(32BIT x 2) なのに、画面上では文字の上や下に斜線
が入るような文字がある。日本語の濁点のようなもの。サに点々を打ってザ
と書くようなのを、サ + ” みたいな二文字で表現するらしい。
そんなものまで日本人が対応しなくて良いと個人的には思ってる。 UTF8 --> UTF16(サロゲートペア) --> UTF32 1 文字
の問題だけでなく、特殊な言語では、
UTF8 --> UTF32 2文字 --> 画面上では 1 文字
の問題が有るということ。
日本人が対応できるのは、UTF32 1文字が画面上で1文字に見えるまでが限界。 >>803
> サ + ” みたいな二文字で表現するらしい
Macってこれだよね
UTF-8-MACくたばれ >>803
>そんなものまで日本人が対応しなくて良いと個人的には思ってる。
欠けリンゴの世界ではそっち採用してるからファイル名の扱いとか厄介だよ >>801
MBCSのsjisとeucに戻りたいかというと、嫌かな(´・ω・`)
今の敵は絵文字 中東とアメリカは中が悪いから、わざと変な文字コードにしたのかも知れんな。
経済的な敵である日本を倒すため、オートリピートなんてそもそも不要なIMEのON/OFF
キーに普通のアルファベットキーよりも開始時間の短いオートリピート機能を付けた
上に、現在のON/OFF状態を画面の右下の分かりにくい場所に小さく表示したりとか
と同じで。 >>811
政治の世界と商売の世界は違いますよ、商売のためならなんでもするのが商売人というやつですよ >>794
スレタイ3回音読してからごめんなさいは? どうでもいいけどオリパラのRPCはリモートプロシージャコールじゃなくてなんちゃってロシア
まめな フフフフフ…で埋められたWin32アプリデバッグメモリを思い出した人、どのくらいいるかな
「フフフ…」4歳娘が撮影した花火に家族で爆笑! 見ると笑顔になる“奇跡の1枚”の状況を父親に聞いた | FNNプライムオンライン
https://www.fnn.jp/articles/-/224754 0xABADBABE がwindows7のUSB
0xBAADF00D がlocal alloc
深淵に到達するとフフフじゃないのよ Debugモードで実行すると配列の中身が「フフフノフフフ」になってワロタ HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);
に渡すhMemは必ずGlobalAllocで確保したものでなくてはいけないのでしょうか?
mallocやnewやスタック領域のポインタを渡すとどうなるんでしょうか・・・? >>825
クリップボードはOS単位
スタックはプロセス単位 >>828
あぁプロセスを跨がないって言った方がよかったな >>826
確かにデータへのポインタであれば長さも渡す必要があるはずですし型名からしても説明からしても明らかに仰る通りでした
>>827
GlobalAllocもあくまでプロセス単位であって、GlobalAllocに書き込んだデータをOSに教える → SetClipboardDataでOS管理化のバッファに渡される(CloseClipboardするまでフラッシュはされない?)
という原理であるはずなので、hMemはスタックやmallocでも良いのでは?と思った次第です
しかしながら単純なデータへのポイントではないという事で納得しました >>830
GlobalAllocと言っても引数に渡すオプションで変わるぞ
GMEM_FIXEDを渡せばプロセス単位でアクセス可能なメモリ(プロセスを超えてアクセスはできない)
GMEM_MOVEABLEを渡すとプロセスを超えて使用できるハンドルが返る
この時点でプロセスのメモリ領域はまだ確保されていない
その後GlobalLockによってプロセスのメモリ空間にマップされる
>SetClipboardDataでOS管理化のバッファに渡される
SetClipboardDataに渡すのはハンドルであってメモリじゃない
言い換えると、システム(クリップボード)は渡されたハンドルの複製を作ってそれを保持するだけ
ハンドルが示すリソースには参照カウンタがあって、すべてのハンドルが閉じて初めて解放される
つまりGlobalAlloc、GlobalFreeでプロセスがハンドルを閉じても、クリップボードに渡されたハンドルが生きているからデータを維持し続ける
新たにクリップボードにコピーや切り取りをするとそれまでの複製されたハンドルを閉じるので参照カウンタが0になり実際に開放されることになる
>(CloseClipboardするまでフラッシュはされない?)
GlobalUnockをした時点で書き込まれたデータはハンドルさえ知っていれば誰でもアクセスできる状況にある
言い換えると「フラッシュされるタイミング」はGlobalUnockしたときと言えるだろう
ただしCloseClipboardすることで「ハンドルの複製」が確実に行われるということではある
プロセスはCloseClipboardを呼び出す前に渡したハンドルの開放を行うべきではないと書かれている
(これはシステムがハンドルの複製する前にプロセスが元のハンドルを解放して参照カウンタが0になってしまいデータそのものが解放されるのを防ぐためだろう) 訂正
× つまりGlobalAlloc、GlobalFreeでプロセスがハンドルを閉じても、
〇 つまりGlobalFreeでプロセスがハンドルを閉じても、 クリップボードを使うときGlobalAllocで割り当てたメモリは解放しなくていいって聞くけど
クリップボードを経由せずにHGLOBAL値を他のプロセスに渡してもGlobalLockでアクセスできないよな
ということはクリップボードもメモリオブジェクトそのものをムーブしているのではなく実はコピーしてるだけ?
だったら貼り付けた側でもGlobalFreeすべきなのかな >>833
>クリップボードを経由せずにHGLOBAL値を他のプロセスに渡してもGlobalLockでアクセスできないよな
あれできなかったっけ? さっきやってみたらできなかった
実験のやり方がまずいのかな FileMappingより簡単な方法があるのかと期待したんだけど >>833
GlobalAllocしたプロセスを閉じた後もちゃんとクリップボード内のデータは残るのと
SetClipboardData → CloseClipboard → GlobalFreeという非公式な手順でFreeをした後もちゃんとクリップボード内のデータは残るため、あくまで実データはOS側へコピーされているという認識でした
メモリビューアで眺めた感じだと成功した後にGlobalFreeを行わなくても、
GlobalAlloc(GMEM_MOVEABLE, size)の戻り値->、GlobalLockの戻り値->共に該当アドレスへ別データ上書きは確認されたので、ちゃんと解放されているものと思われます https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-setclipboarddata
> The application may not write to or free the data once ownership has been transferred to the system
ないね SetClipboardData の第一引数は CF_PRIVATEFIRST + 定数 だったりするのかな なるほど
クリップボードがメモリオブジェクトをGlobalFreeしているので
アプリ側でGlobalFreeすると二重解放になるのは
ムーブかコピーかによらないってことか 「メモリ割り当て方法の比較」という
MicroSoftの資料を一読したら?
GlobalAlloc はHeapAllocのラッパ Win16の頃のドキドキひやひや感が無くなったよな Windowsゲームプログラミング (Game developer) 単行本 – 2004/5/1
最新版 12歳からはじめる ゼロからのC言語ゲームプログラミング教室
ってWIN32API始めたての人でも読んでも難しくないでしょうか?
読んだことある方いらっしゃいましたら教えていただきたいです。
書籍スレで同じことを聞いたのですが内容に関して教えてもらえなかったのでこちらで… >>857
あなたの頭の出来までは分からないから
難しいかどうかは分からんなあ
見たことないから知らんけど 素人:本が判り易いかどうかを聴く
普通の人:その本で何が出来るかを聴く
出来る人:その本が役に立つかどうか自分で考える >>860
CとC++の入門書2冊ずつやった程度です。
素人レベルなので0からでも分かるかどうか教えてほしいです。 >>859
32Bitじゃなくて新しいWIN32APIの入門書もあるのでしょうか?
古い技術だからかAmazonで色々漁っても古い入門書しか見つからなかったです Windowsゲームプログラミング (Game developer) 単行本 – 2004/5/1
これは2版がでてるはずだが
ちなみにC言語がわかればド素人でも理解できるように書かれてる 推薦本のスレにも書いたけど、
基本、年齢が入った本は、ジャケ買いする人に買わせる本。
タイトルによる釣り
慶応卒のRubyの女神・池澤あやかが言ってるけど、
大学生のほとんどが、Cの授業で挫折する
だから中学生で、Cを理解できる確率は、1億分の1ぐらい
単に、そのままコピペして動かすだけの本。
ポインターなどを理解させる事は、絶対に無理
それに、コピペ・日記本の類は、単に手順書で、少しでも古いと動かない。
こう書いたら、こう動くというだけの本
まあ、図書館で読んでみれば?
君らの事を、情報弱者(情弱)と言うけど、
本のタイトル以外に、情報を持っていないから、年齢に頼ってしまう
漏れらは、慶応ぐらいでも、ほとんどの大学生が、Cで挫折する事を知っているから、
最初から、中学生には無理なことが分かっているから、タイトルに引っ掛からない 俺FランだけどフリーランスのCプログラマだよ
学校の偏差値とか全然関係ないから 基本的に、パソコンゲームは数十年前の話。
今は、Windows用・Linux用のゲームはない
Android用ゲームだけ。
皆、Unity を使う
ブラウザゲームなら、Pixi.js ベースのPhaser とか
下のサイトのイタリア人は、昔は、cocos2d-js も載せていたけど、
今は、Phaser ばっかりになってしまった
https://www.emanueleferonato.com/
ゲームは、ゲーム製作板の方で聞いた方がよいけど、
基本、DirectX などのパソコンゲームは存在しない。
誰も作らない
作っても売れないから。
今、パソコンゲームを買う人は、いないでしょ Ruby妖怪がSteam見たらひっくり返りそうやね
イヤ見なかったことにして脳停止できるから妖怪なのか >>863
64bitAPIアドレス周りが、ちっと違う SetWindowLong(), GetWindowLong() が変わる
引数のマクロ定数も変える必要が出てくるケースあり C言語で32/64bit対応するのはわりと簡単。最新コンパイラのコンパイル時警告に沿ってソースを修正すればいいだけだから。
問題はWin32APIをDLL呼び出しするスクリプト言語での対応で誰も親切に警告してくれないし、アセンブラ並みに面倒。 64bitで困るのはWin32APIの部分じゃなくて
SysWOW64の部分だったりする アドレス空間が違っててハンドルをプロセス間で共有できなかったりするんだったか? regedit も system32 の部分と syswow64 の部分の両方ケアしないといけないし面倒になったよね 32bit アプリが 64bit 環境で動いていて そいつが参照するレジストリは
syswow64 側に居て そっちを書き換えないといけないとかあったな ODBC 登録リストも 32/64 で別々だった気が うちの Windows 10 のスタートメニューには
ODBC Data Sources (32-bit)
ODBC データ ソース (64 ビット)
があるが何この中途半端な日本語化ωωω >>879
COM(OLE/ActiveX)のクライアントがサーバーにDispatch出来なかったりするんだよな DirectX の Filter も 32/64 両方造ったし
GraphEdit も両バージョン立ち上げて確認してるんだが Unix由来の標準入出力とソケットが一番頼りになる皮肉 むかしむかしX Window Systemの内部通信は…… Windows 11 出たけど
Win32API 関連はなんか変わる?
注意点とか?
「アプリ」は使わんが loadImageFile関数について教えて下さい
以下の書き方でエラーが出るんですが何処が間違えてますか?
img.loadImageFromFile("C:\Program Files\Cheat Engine 7.3\autorun\test.jpg")
エラー内容 invalid escape sequence test '" C:\P" エスケープシーケンスがなんだか調べたらどう?
こんなの基礎知識 漏れは、Ruby で、/ をパス区切りに使っているけど。
Dir.glob( 'C:/Users/Owner/Documents/**/*.txt' )
特殊文字をエスケープするなら、\ は、\\ になるのかな? >>891
"C:\Program Files
↓
"C:\\Program Files C++ならR"(ここはエスケープ不要)"なんてのが使える C++ならって言うけど、それができるのはC++11対応以降だぞ とりあえず物理ローカルドライブのパーティション1は開けるかね? >>891
エラー文をちゃんと読むようにしたほうがいいよ。 コンボボックスのリストアイテムのフォント色を変えようと思ったんだけど、リストコントロールの親ウィンドウが他プロセスcsrss.exeなのでWM_NOTIFYを受信できない
どうすればコンボボックスのリストアイテムのフォント色を変えられるだろうか? >>903
回答ありがとう
だがしかし、ownerdrawはWM_DRAWITEMが親ウィンドウに送られてくるので、コンボボックスのリストコントロールの親ウィンドウが別プロセスという問題点は同じ >>905
回答ありがとう
だがしかし、customdrawはWM_NOTIFYが親ウィンドウに送られてくるので、コンボボックスのリストコントロールの親ウィンドウが別プロセスという問題点は同じ
ちなみにコンボボックスのリストボックスは、SendMessage(CB_GETCOMBOBOXINFO)で戻されるCOMBOBOXINFO構造体のhwndListからウィンドウハンドルを得ている
コンボボックスのリストボックスは最初から親ウィンドウがデスクトッププロセスcsrss.exeが所有しているウィンドウクラス名「#32769」となっている >>906を訂正
リストボックスではなくリストコントロール >>908
回答ありがとう
だがしかし、WM_CTLCOLORLISTBOXは親ウィンドウに送られてくるので、コンボボックスのリストコントロールの親ウィンドウが別プロセスという問題点は同じ
>>909
回答ありがとう
だがしかし、LVM_SETTEXTCOLORはリストコントロール全体の文字色が変わってしまうので避けたい所存 コンボボックスのリストコントロールは常にクラス名が「ComboLBox」で、親ウィンドウは必ずプロセスcsrss.exeが所有するウィンドウクラス名「#32769」のデスクトップウィンドウになる >>911
回答ありがとう
メッセージフックはまだ試していないけど、WM_NOTIFYやWM_CTLCOLORLISTBOXはプロセス間やスレッド間で送受信できないとのことなので、一旦あきらめることにします >>917
回答ありがとう
だがしかし、サブクラス化してもコンボボックスのリストコントロールの親ウィンドウが別プロセスという問題点は同じ
拡張コンボボックスつまり >>913で教授いただいたCComboBoxExを試すのに時間がかかりそうなので質問は終わります サブクラス化して WM_DRAWITEM と WM_PAINT を処理するだけでカラーリスト作ったことあるけど俺環だからだな ハンドルは取れるんだから(Read|Write)ProcessMemoryやら使えば何でもできるよ ▼押してポップアップするリスト側の表示をどうこうしたいっぽい
(自前で実装してもそれまでのような気もするな) だから919でそれやってるんだけどね
親が別プロセスになったらこのメッセージが飛んでこなくなると言うなら知らん そもそもリストコントロールの親ウィンドウにWM_DRAWITEMが投げ込まれる仕様なので >>919,922 は何かの記憶違いじゃないかな 手元のソースを見ながらレスしたんだけど、
親ウィンドウ(プロセス)から作った子ウィンドウ(COMBOBOX, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED コントロール)
のサブクラス化だけでそっちにメッセージはちゃんと来ててリストの色分けとかできてる
親プロセスが別という話ならテストしてないから知らんし、手元のソースも WM_DRAWITEM を処理してるところが他にないので
これ以上調べる気は無い >>924
詳しい説明ありがとう
普通のコンボボックスを(CBS_DROPDOWN | CBS_OWNERDRAWFIXED)で作成後、そのコンボボックスをサブクラス化することで
コンボボックスでWM_DRAWITEMを拾えるようになりました
CBS_OWNERDRAWFIXEDをセットし忘れていたことができない原因でした
大ポカです コンボボックスはスタイルにCBS_NOINTEGRALHEIGHTを追加すればドロップダウンリストの自動リサイズを抑止できるんだけど、
表示後の明示的なリサイズはどうすればできますか? >>930
COMBOBOXINFO.hwndListとSetWindowPos/MoveWindowを使う。 >>931
CBN_DROPDOWN通知時にhwndListでSetWindowPos()を試したけど反映されなかった
どのタイミングならサイズを変更できるのだろう? リサイズしようとしたら
WM _ GETMINMAXINFOが出て
それを処理しないといけない。
なので、独自にメッセージをポンプするか、PostMessageで現在のメッセージ処理を
一旦終了させないといけない。
直前に書いてある回答の蛇足だとこんなもん >>930,932 の質問の表現を変えます
CBS_NOINTEGRALHEIGHTスタイルのコンボボックスはrcファイルで指定されたドロップダウンリストのサイズを維持しようとするらしい
WM_INITDIALOGでコンボボックスのフォントを変えるとフォントに応じてドロップダウンリストのサイズも変わってしまう
WM_INITDIALOG後にコンボボックスのドロップダウンリストのサイズを変更するにはどうすればよいか? むしろフォントに応じてサイズが変わるのが正解
メッセージ処理のタイミングなどで動的変更する方法は知らんが、
ダイアログリソースを編集すればワンチャン
ダイアログ表示してから編集というのはしたことないから保証しない(というか無理なきはする)が
表示前なら編集してどうにかなる コンボボックスのドロップダウンリストの縦サイズはデスクトップの縦サイズの半分より十分小さくないと、
コンボボックスが縦方向中央付近にある時にテキストボックスがドロップダウンリストに隠れやすくなる 面倒なので試さないけど、もしかしてフォント変更後にコンボボックスコントロールの
ウィンドウハンドルそのままSetWindowPosに投げたらドロップダウンサイズ変わらんか? a.exe という service 用の exe があるとして
その WinMain の中で
登録済みの service (a.exe) として実行されたときと
デスクトップから起動 (a.exe) されたときと
区別する方法はありますか? >>939
GetModuleFileNameで実行ファイルの場所がわかる。 デスクトップって言うのはダブルクリックで起動って読み替えたけど違うんかな ・実行ファイル自体は同じ場所にある
・(ダブルクリックによる)エクスプローラーからの起動
・システムのサービスに登録してての起動
実行ファイル側のコードで自分自身で区別することが出来るか? という話でいいのかな? ショートカットファイルならコマンドラインオプションをつけることができるから、それで区別可能。 サービス用のEXEをそのまま実行する仕組みなんて普通は作らないけど
そのプロセスを起動した親のPPIDで判別できると思うよ 親プロセスがservices.exeかどうか見るとか。結構めんどくさそうだけど .NETにはPPID取得する方法が用意されてないのが驚きなんだよね
WMIかピンボケするしかない 独自のコマンドラインオプションをつけたものをサービスとして登録して、
それがついているときはサービスとして動作するように作ってる >>939
ServiceMain とWinMainで入口から
違うが? >>941
cmd とかからのコマンド指定で起動も含みます
>>942
それです
>>944-946
ひと手間だけで取得出来る一般的な API やパラメータは無さそうですね?
>>947
それは最初に思い付いたのですが元々起動時のパラメータや API で取得する方法があるならその方が良いかなと思いました >>948
アプリケーションのエントリポイントは WinMain (or main) で変わらんでしょ
その中で登録だなんだを経てWinMain からは抜けるけどプロセスは生き残ったまま
別スレッドで ServiceMain をディスパッチしてるだけじゃなかろうか >>950
そんなコードは無いな。
どこの資料にそんな事書いてあるのかね? サービスのAPIってWindows NTの時代からたいして変わってないだろw NT4 から2000でSCMの動的ロードが出来るようになったな >>951
WinMain(またはmain)内でStartServiceCtrlDispatcherを呼ぶ以外の方法あるの? yes.It's the power of Christ that compels you! IOCTL_DISK_GET_DRIVE_LAYOUT_EXで得られるパーティションの情報と
FindFirstVolume, FindNextVolumeで得られるボリュームとの
対応付けはどうやるんです? >>958
何をやりたいのかわからないけど、IOCTL_DISK_GET_DRIVE_LAYOUT_EXの情報からドライブ名にしたいのなら、
"\\?\Volume" + PartitionId(GUID) にすれば、ボリューム名になるのでそれを変換すればいいはず WS_EX_TOPMOSTなウインドウが時々、
通常ウインドウごときに前に出しゃばられるんだけど
防ぐか、出しゃばられたのを自動検知してZオーダーを
奪い返すにはどうすればいい? 他所の窓が WS_EX_TOPMOST で奪っていって前に出しゃばられてるのであれば
WM_STYLECHANGED 捕まえて奪い返す? >>961
もしかして
そうなった時って一度アクティブにしたらなおるやつ? CreateWindow直後は理屈のとおりなんだけど
長時間稼働させて忘れた頃にAdobe Readerだの一太郎だのに
前に出しゃばられてるんだ >>961
WM _ windowposchanging 質問します
自作ソフトからのドラッグアンドドロップで
デカいファイルのコピーなどで DoDragDrop から長時間制御がかえって来ないことを嫌って
DoDragDrop に渡すデータオブジェクトに IDataObjectAsyncCapability を実装しています
これで、D&Dが非同期になり、データのコピーなどが始まると、StartOperation が呼ばれ、
終わると、EndOperation が呼ばれると思っていたのですが・・・
で、何がしたいかといいますと、自作ソフトからエクスプローラにファイルなどをD&Dをしたとき、
エクスプローラが自作ソフトのプロセス中の IDataObject を
使用している間は自作アプリの終了を出来ないようにしたいわけです(なぜならエクスプローラが使用中だから)
それで、StartOperation でカウンタを一つ上げて、EndOperation でカウンタを一つ下げれば
現在なんらかの IDataObject が使用中かどうかわかるので、その間は終了できないようにしたいわけです
ところが、実際には、StartOperation は呼ばれますが EndOperation は呼ばれません!(なぜ?)
Win10 と Win11 の両方で試しましたが、両方ともそうでしたのでそういう実装なのでしょう
そこで、IDataObject のデストラクタ をもってして EndOperation の代わりにしようと考えました
IDataObject の参照カウンタが0になって解放されたなら、だれも使ってないことは確実なので、、、
で、エクスプローラは IDataObject を使い終わったら素直に Release してくれるのでいいですが
そうでないソフトもあります、具体的には Visual Studio 2022 がそうでした
勝手な想像ですが、おそらく IDataObject の解放が GC 任せになっているのでしょうか、いつ解放してくれるか分かりません
問題は、Visual Studio 2022 に直接ドロップしなくても
D&D 中に少しでもマウスカーソルが Visual Studio 2022 のウィンドウの上を通過するだけで
Visual Studio が IDataObject を握ったままになることです
探せば Visual Studio 以外にも、特に .Net 系のアプリなんかで IDataObject の解放を
GC任せにしているアプリはあるんじゃないですかね
そういった経緯がありまして、どのタイミングでファイルのコピーなどが終了して
アプリを終了してもい状態になったかどうか、判断する手立てがなくて困ってます
何かいい方法ないですかね Ruby なら、まずデスクトップに、Rubyスクリプト・a.rb を起動するショートカットを作る
ショートカットのリンク先
C:\Ruby25-x64\bin\ruby.exe C:/Users/Owner/Documents/a.rb
a.rbの内容は、以下のように、
DryRun を使っているので、実際にはコピーされない
普通は、以下のように同期処理で作るけど、非同期にしたいのなら、
別プロセス・worker process でも起動すれば?
require 'fileutils'
dest_dir = "C:/Users/Owner/Documents/tmp/"
# ARGV は、ドロップした複数のファイルパスの配列
ARGV.select { |full_path| File.file?( full_path ) } # ファイルのみ処理する
.each do |full_path|
file_name = File.basename( full_path ) # ファイル名のみ
FileUtils::DryRun.move( full_path, dest_dir + file_name)
end
sleep # 出力したコマンドプロンプト画面を閉じないようにする
出力
mv C:\Users\Owner\Documents\x.txt C:/Users/Owner/Documents/tmp/x.txt 上のキチガイも書いてるがそういう場合は別プロセスにして放置だな
単一プロセスでうまくいかない事なんて沢山ある そうですね、確かにただのファイルのコピーなら別プロセスで実行してもいいのですが
ドラッグアンドドロップと絡んでくると難しいんじゃないですかね
なにせ実際にファイルのコピーを行うのは自アプリじゃなくて
エクスプローラ側のなのでですね
別プロセスで DoDragDrop を呼び出せってことなんでしょうけど
ドラッグアンドドロップの起点となるのはメインアプリのマウスメッセージからなので
これはかなり難しいと思います
なにせ DoDragDrop は別スレッドから呼び出しただけで動かなくなる変なAPIなので
http://bbs.wankuma.com/index.cgi?mode=al2&namber=94173&KLOG=163
別プロセスとなるとさらにハードルが高いと思われます
なぜ別スレッドで DoDragDrop が呼び出せないかは謎なんですが
多分 Windows 内部で WM_LBUTTONDOWN 系の何か「今」マウスが押されてる
ウィンドウかスレッドを覚えていて、それとは別スレッドで DoDragDrop が実行されると
失敗する処理が入っているんだと思います
ドラッグアンドドロップはかなり、なんというか、まぁ、特別というか
他のアプリにも影響が出る処理なので、OS全体を巻き込んでフリーズしないように
何かしてあるんでしょうね、これ、ちょっとよく分かりませんが、、、
ともかく別スレッドで実行できないです、なんででしょうね
それを回避するのが IDataObjectAsyncCapability なんですが
https://docs.microsoft.com/en-us/windows/win32/api/shldisp/nn-shldisp-idataobjectasynccapability
MSDN にも StartOperation が呼ばれたら、データ維持しろ、みたいなことが書いてあるけど
それをいつまで維持すればよいのかという話で、最後に EndOperation が呼ばれるって書いてあるけど
実際には呼ばれないんですよねー、まぁ呼ばれることもあるんですけど、この辺がまた一貫してない DialogBoxでメインウインドウを作るとタイトルバーのHeightが若干短くなるものと認識していたのですが、色々とスタイルを試しても一般的なウインドウと同じものしか出来上がりません
世に出てるダイアログベースのフリーソフトは短いものが多いと思いますが何が違うのでしょうか? 自分で描いてるんじゃね?
spy++で属性見るべし >>979
> DialogBoxでメインウインドウを作るとタイトルバーのHeightが若干短くなるものと認識していたのですが、
そのようなことはありません
> 色々とスタイルを試しても一般的なウインドウと同じものしか出来上がりません
それが通常です
> 世に出てるダイアログベースのフリーソフトは短いものが多いと思いますが何が違うのでしょうか?
思い違いです
WS_EX_TOOLWINDOW を付与したウィンドウを求めてるだけじゃないのですか? >>980->>982
返答ありがとうございます
spy++で全く同じスタイルを付与してもタイトルバーの長さは変わらず太いままでした
短い方のフリーソフトにはWS_EX_TOOLWINDOWは立ってないようです
そして色々とググってみた所stackoverflowの質問によると、manifestにて最小サポートOSをWindowsXPにすると短くなるみたいな仕組みっぽいです
https://stackoverflow.com/questions/32426055/windows-10-dialog-box-titlebar-behavior この値ってファイル重複は調べられないのね
ハードリンク、シンボリックリンクだと同一の値だったが
(unsigned __int64) nFileIndexLow + ( (unsigned __int64) nFileIndexHigh<<32) 上のファイルIDって、ボリュームごとにナンバーがつけ変わるんですか?
そもそもどのようにファイルIDが生成されてるのか不明なんですが
コピーだと別のIDになりましたが
ボリューム番号を付けないでファイルIDが一致した場合、全く別のファイルってことがあるんですか?
ファイルの同一性判定
Windows
ボリュームシリアル番号とファイルIDを用いて同一性判定を行う。
https://yohhoy.hatenadiary.jp/entry/20130311/p1 ファイルIDが変更されるルールが不明なんですが
その昔の nFileIndexHigh/Low の日本語説明はこうなっている。
この識別子とボリューム シリアル番号により、 ファイルが一意に識別されます。
この番号は、 システムの再起動時やファイルのオープン時に変更される場合がありますが、
プロセスがファイルをオープンした後は、 識別子はファイルがクローズするまで一定の値になります。
アプリケーションはこの識別子とボリューム シリアル番号を使って、 2つのハンドルが同じファイルを参照しているかどうかを判断することができます。
成る程、比較にはボリューム シリアル番号も含めねばならぬ。
当時の「ファイルオープン時に変更されるかも」の文言の真意は判らないが、nFileIndexHigh/Low を長期間保存しておくのは問題有るかも知れない。
usskim.blog37.fc2.com/blog-entry-555.html dbgviewの後継ツールってないの?
特定のプロセスだけ監視するとか
大量のゴミ撒き散らしてるプロセスだけ除外するとかしたい >>991
dbgviewのFilter機能じゃダメなの?
>特定のプロセスだけ監視とか
>大量のゴミ撒き散らしてるプロセスだけ除外するとかしたい
自分が作ってるアプリなら、Traceの頭に固有文字列付けとけばよいし、
そうで無いなら[プロセス番号]でフィルターすれば事足りると思うが? >>987
FATならディレクトリの最初のクラスタと、ファイルのバイトオフセットから生成
デフラグによってそのクラスタ位置やバイトオフセットが変われば識別子も変わる
削除して別のファイルを生成した場合に、同じファイルIDが生成される可能性がある
NTFSなら削除されるかReplaceFileによって置き換えられるまでは一意
またFAT、NTFSともにファイルIDはファイルシステムごとだから、同一コンピュータ上でも論理ドライブが違えば被ることもあるので、
同じ論理ドライブか異なる論理ドライブかを判断するもの(ボリューム シリアル番号など)が必要 デフラグやファイル操作で変わるなら何の意味もないように見える
活用したい場面なんてないのでは 1000ならこのpartスレはこのスレで終了
未来永劫立てるなボケガイジ低学歴低年収底辺ども
しねしね このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 586日 22時間 41分 57秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。