Win32API質問箱 Build127
>ミューテックスを使うとなると、事前にミューテックスの名前も決める必要が出てくるのですが。 別にそんな必要はないでしょ ユニーク名+ファイル名でミューテックスを使えばいい (※ユニーク名ってのは自分しか使わない名前のことね、例えばGUIDとかだけどそこまでがっちりやる必要もないとは思う) >>551 指定できる最大値を設定しておけばいい > ファイルの現在の終了位置を超える領域をロックすることは、エラーではありません。 とあるから事実上ファイルそのものをロックしたのと同じ >プロセス間で同じファイルを読んだり書いたりしたい 問題を無闇に複雑にしてると思わないか クライアント・サーバーモデルで、 サーバーだけが書き込めるとか言った制約があった方が良いかも知れません。 アドバイスありがとうございます。 あるアプリから別のアプリを起動する際、 コマンドラインでは収まらないような長い情報を渡す必要があり、 ファイルに必要な情報を書いてやりとりするようにしています。 (コマンドラインにはそのファイルのパス名を渡している) なので、ファイルを作成するアプリと、そのファイルを読み込むアプリがあり、 多重起動などのタイミングによってはアクセスがぶつかる可能性があるので、 このファイルに対する同時アクセスを制御したいという質問でした。 ミューテックスとLockFileExとどちらで実装するか、検討させていただきます。 >>554 コンパイラとリンカで同じファイルを読んだり書いたりするのも 問題を無闇に複雑にしているのか? >>556 それはやり方が違うだろ GetTempFileNameとか使って一時ファイルを作成すればすむ話 >>559 それもやってみたのですが、多重起動などのタイミングによっては、 どうやっても、読み込まれずに放置されるゴミファイルができてしまいます。 テンポラリフォルダなんて気にしなければよいといえばよいのですが。 Tempなんか使わずとも末尾PIDの名前でファイルなりを作れば重複起動その時においては名前は被らないし 引数の受け渡しとか程度の話ならオープン失敗したら数秒待って開き直せばいつか開けるだろ 書いてる間はどうせ読めても無意味なんだし WM_COPYDATAとかメモリマップドファイルとか >>556 >>558 と被るけど名前付きパイプがお勧め。 >>560 いや、ゴミファイルが出来る事があり得ないけどね… その多重起動というのがどういうものか知らんけど、GetTempFileNameで上手く行かないのは、プログラムが悪いと断言できる ま、これで駄目なら何やっても上手く行かないだろうね >>548 twitterで流行ってたものを誰かが試した結果を見て気付いた。 >>565 それで遊んでみようと思ったのだけど何を使用していたのかわからないなら遊べないな残念 >>490 正確にはMFCはMS-DOSの開発ライブラリ だからGUIのWindowsとうまく噛み合わなかった Ruby では普通、外部コマンド・子プロセスの終了を待つから、実行順序は書いた順。 Process.#wait 一方、Kernel.#spawn は、終了を待たない。起動しっ放し IO にはパイプ、ブロッキング/ノンブロッキング、同期/非同期もある >>567 コマンドベースの開発ライブラリならSDKだろ MFCはGUIが前提のクラスライブラリとアプリケーション構築のプラットフォームをセットにしてWin32APIをラップしたもの >>567 これはひどい そんなの関係ねぇ GUIのWindowsとうまく噛み合わなかったのは MSVCの開発陣がC++への理解が足りなかったから インストーラーの無い野良EXEのAUMID(Application User Model ID)をOSに登録する方法教えてください >>570 Microsoft Cがいつからあるのか知らないのか。 MFCにはGUI限定などという定義はない。 そもそもMFCはCUIのライブラリから始まっている。 >>570 SDKの意味すらわかってねえのか? あんたのいうMFCは、Windows SDKが扱うWin32APIをさらにラッピングしたMFCのことだ。 あんたの言っていることは滅茶苦茶だ。 >>571 どうでもいいけど、マイクロソフト内でC言語とC++の混在そのものに悩んでいたのも知らないようだな マイクロソフトはC言語派、C++派、Windowsを普及させるためにVB流用派と、試行錯誤を繰り返していた時代にMFCが誕生したと思っているなら、時期がずれていてリアルタイムでは知らなかったと言っているようなもの MS-DOS の頃ってMSのコンパイラは統合環境だった? C++ どころか Cコンパイラで コマンドライン上から nmake 叩いてわ ウィキペディアの説明が、Microsoft C 7.0以前の話がないせいで、Microsoft CとVisual C++の区別がついていないのね。 Windows 95、98の時代は、MS-DOS 6.2とWindows 95・98(内部MS-DOS 7.0・7.1)の併存期間で、MFCはMS-DOS 6.2をターゲットとしたものと、Windows 95をターゲットとしたものがある。 まず俗称「MSVC」と呼ばれるものは、Windows 95アプリケーションの開発を意識したもので、マイクロソフト「VC」と言っているあたりからわかるようにC言語でのWindows 95アプリケーションの開発を主としている。 ここでC言語からC++の移行をマイクロソフトはやろうとして、Windows APIがオブジェクト指向ではないところで無理が生じた。 そこでMFCを大幅に強化することでC++でのアプリケーション開発をしてもらおうとしたが、すでにWindows SDKの開発の知識がある開発者は、Windows SDKでのCでもC++よいというのに慣れていて、MFCを使えというのは、それまでの知識と違っており、無駄なクラスライブラリとしか思えなかった。 MFCはWindows 3.1でも影が薄い。マルチタスクではないと言えてしまうWindowsでは、MFCのメリットなどなく、無駄にサイズが大きくて重いコードが作られるため、性能、スペックの低いパソコンではMFCを使う理由がなかった。 MFCはGUIだけで使われるものではないため、CUI環境の開発でも使われている。 MFCどころかWindows 32APIでも、画面がある前提になっているコードを書かないといけないが、実際には画面がないものを作るのにも使われる。 MFC、Visual C++、Windows SDKの話がごっちゃになって、MFCを使うにはVisual C++でMFCを利用して、MFCがWindows SDKとセットだと認識できない点は理解できる。 まあ、ウィキペディアの記事は、根拠不明の創作が多いとわかってないとだまされるよな。 Win32がオブジェクト指向ではないって? ハンドルを使う関数(つまり大半)はオブジェクト指向だと思うが もしかしてオブジェクト指向とはC++やSmalltalkを使うことだと思ってるのか? >>578 統合開発環境と何の関係があるのか? Windows 95アプリケーションでも、統合開発環境は必須ではない。 画面のデザインのときだけ利用するという使い方が多かった。 Direct Xが普通に使われるようになってからは、統合開発環境は画面ごと吹っ飛ぶので、統合開発環境そのものも動かないこともあるし、統合開発環境を自分が作ったもので壊すことがあるから、Windows 95、98系では、Visual製品に期待しても、Visual統合開発環境とWindows OSのポンコツコンボは、いま思っているより意味をなしていなかったんだよ。 >>582 MFC=マクロ出力とセットになった統合環境前提って印象だったものでね リソース周辺のアレ >>581 そこで使われるオブジェクトとオブジェクト指向とは関係ない アセンブラのオブジェクトファイルと同様だ >>581 オブジェクト指向設計ではなかったんだよ。 C言語とC++は書き方が少し異なるだけだったので、Windows SDKではC++で書くとオブジェクト指向っぽくなり、C言語で書くとこれでいいのかという書き方で、Windows 95のアプリケーションが作れた。 ここはWindows SDKがオブジェクト指向ではないという理由がある。 APIそのものはオブジェクト指向ではなかったので、オブジェクト指向にするにはMFCを挟むという変なことをすることをしていた人間もいる。 たった数年で変わった話なので、過渡期を知らないと誤解が生じるのはわかる。 >>584 GetObject()なんか多相そのものやん すまん関数名間違えた SelectObject()だ GetObject()はオブジェクト指向と手続き型の切り替えだね Win32APIの基本構造そのものがイベントドリブンのメッセージ駆動なのでオブジェクト指向を土台にしている Windowsのマルチタスクはオブジェクト指向で成り立っているだろ そうそう ウインドウプロシージャのcaseなんか典型的だな >>575 >そもそもMFCはCUIのライブラリから始まっている。 doubt >>577 でたらめ言うなよ ボケが始まってるんだな爺さん ばあさんかも試練が >>580 おまいは Windows 3.1 の知識が抜け落ちておるな >>585 むしろ Win(32以前も)API / Win32API がオブジェクト指向で MFC の方がオブジェクト指向出来ていなかったんだよ だから判ってる香具師はみんな MFC は使わなかった 使ってたのは馬鹿だけ >>594 APIについてはその通りだが MFCがOOPでないという主張には 賛成しかねる 下手なところがあるのは俺も認めるが 原理主義者の言いなりである必要はない MFCとかけて、C++と解きます その心は、オブジェクト指向ではあるけど、なりきれていない これでどうでっしゃろ GUIの無い単純なアプリならまだしも、それなりのGUIを持つアプリは MFCを使ったほうが楽にアプリを作れるし、出来たコードも読み易い 確かに最初はMFCは取っ付き難いから、そこで挫折した人が >>590-594 みたいな事を言い出すんだろうなあ >>599 そんなことは無いと思うが Win32APIをちゃんと知っていればMFCなんて使う理由が全く無いし MFC関連のDLL何かも入れないといけないし単に開発効率がおちるだけ 実際当時Windowsアプリの仕事を結構やったけどMFCを採用していた所は少なかった たまたまそういう場所ばかり行ってた可能性はあるがMFC何て使うなよって当時から思ってたよw でも世の中的に勝利したのはMFCだよね 俺もATL/WTLでいいじゃんとは思ったけど でかいライブラリも整備されてりゃそれなりに便利だからね仕方ないね >>578 PersonalWorkBenchってのでFortranやったような気がするんだが 今ググっても全然出てこないな VB→.NET の流れがGUI開発の勝ち組というなら分からなくもないが MFCは・・・ >>600 >Win32APIをちゃんと知っていればMFCなんて使う理由が全く無いし WindowProcに case WM_… をだらだら書かなくても済むだけでも大きな利点 >MFC関連のDLL何かも入れないといけない ユーザー層やアプリの配布形態に応じて、必要ならMFCをStaticLibraryでリンクしてしまえば良い >>602 >VB→.NET の流れ 社内ツールとかならともかく、それこそユーザーにVB入れさせるなんて問題外でしょ 大量のデータ処置を行うようなアプリでは処理速度も遅いし 一般販売されてるアプリでVBで作られてるものなんてある? DLL hell, OCX hell とかVB案件の負の遺産なんじゃなかろうか >>600 >MFC関連のDLL何かも入れないといけないし単に開発効率がおちるだけ 昔Win32+CだけでDLLの追加が要らないよう頑張ってみたこともあるけど辛かったね。 C++の機能使ってしまうと結局CランタイムDLLが必要になるし。 >>601 だよな 8086しかりwindowsしかりMFCしかり 技術的に劣っていてもデファクトになると 好むと好まざるに依らずそれ関係の仕事が来る 元々BSD使いだった俺がwindowsに転向したのもメシのため DLL便利じゃん プラグインで機能後付けもこれのおかげだし >>603 BtoCよりBtoBの方が物は多いと思うが 金融界隈では未だにVB6が現役だし MSにしては大成果だったと言える Windows API インデックス https://learn.microsoft.com/ja-jp/windows/win32/apiindex/windows-api-list Windows API を使用すると、各バージョンに固有の機能を利用しながら、すべてのバージョンの Windows で正常に実行されるアプリケーションを開発できます。 (これは以前は Win32 API と呼ばれていたことに注意してください。 Windows API という名前は、16 ビット Windows でのルートと 64 ビット Windows でのサポートをより正確に反映しています)。 Windows11でPrintDlg使って印刷すると1度目は印刷できるけど 2度目はPrintDlg()呼ぶと反応無しになるのはなんか間違ってるのかな レジストリ弄ってLegacyなダイアログにしとくと印刷できる、あと管理者権限でプログラム実行して 印刷も勝手にLegacyなダイアログになるので印刷できるんだけど 試しに、VC2022で新規プロジェクトで雛形ちょっと弄って試してもやっぱり 2度目のPrintDlg()呼び出しで無反応になっちゃうんだっけど debuggerで見てもPrintDlg()呼び出しでエラーも何も出てこなくてわからない 10で平気なら11のバグだな 窓板の11バグ多すぎワロタスレに報告しとけよ PrintDlgってcomdlg32.dllだよな comdlg32.dllはバグで有名なやつじゃないか Microsoftの直接的な関係者ではなく、TSF (Text Services Framework)の仕組みを知り尽くしている人を募集中。成功報酬あり。 katayama.hirofumi.mz@gmail.com Firefoxのにゃるるにコンタクトすれば? あと成功報酬ではなく労働報酬あるいはコンサルタント報酬であるべきだよ 書き込めなかった、ローマ字で検索して にゃるる が地球にいたころ って言うか自分で勉強検索してたら最も頻繁に出てくる WaitOnAddressってアドレスの値が比較対象と違う値に変化したら自動的に起きるっていう魔法みたいなものではないんだね 呼んだ瞬間に比較対象と違ったら即返る、同じだったら後ほど変わったとしてもWakeByAddress系で通知しなきゃ起きないっていう原始的なイベントと言うほど変わらない感じか directoryなら監視してくれるけど https://www.youtube.com/watch?v=hKLBPXg8oik 呼んだ瞬間に比較対象と違ったら即返る 同じだったら返らない っていうのを期待してる? >>626 その挙動は既にWaitOnAddressに組み込まれてる訳だけど 対象アドレスの値が変わったら通知とか無しに自動的に戻ることを期待していた そうじゃなくてマニュアルでWakeByAddress呼ばなきゃいけないからイベントとそこまで変わらんなぁと まあハンドル作らずに済む点で手軽ではあるけど 8で追加されたAPIは頭悪い OSが頭悪ければAPIも頭悪いという当然の帰着 APIを使うだけならWin32よりWinRTの方が簡単でしょ >>630 ウィンドウ表示するコードはこれだけ #include <windows.h> #include <winrt/Microsoft.UI.Xaml.h> using namespace winrt; using namespace Microsoft::UI::Xaml; int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) { init_apartment(); Application::Start([](auto&&) { Application(); Window window; window.Activate(); }); return 0; } ラッパー系は手をつけにくいなあ、MFCやOWLの悪夢が蘇る 便利そうに見えて、覚えることが増えるだけだったり 見えざる制約が足枷になったり、バージョン管理が面倒だったりと やむを得ない場合は仕方ないけど WinRTってMS的にはWin32と同列の扱いだけど、WinRTは内部でWin32を使ってるのだろうか? COMを焼き直して名前変えただけと言えばいいのか ただCOMの利点だったIDispatchで適当な言語から扱うみたいな事ができないうんこです WinRTはC#の情報ばかりでC++の情報が少ないから苦労するかも その点Win32は情報が多いからいいね >>628 WaitOnAddressは利便性目的ではなく手軽さ+パフォーマンスが要点だからそうとも言えない Thread立ち上げて立ち上げたスレッドがある地点まで到達するまで待ちたいみたいなちょっとしたシーンでは結構便利 パフォーマンス的にもイベント待ちに比べて1000倍近く早かったはず Chromeのタイトルバーに「^」の文字を上下反転させたボタンがあって押すとミニウィンドウ的なのが開くのですが、このボタンを実装したいのですがどうしたらできますか? Chromiumのソースコード見てもどこに該当コードがあるかわかりませんでした c言語で実装したいです タブを検索ボタンか。ソースをTab Searchで検索すれば出てくるんじゃないの 検索してみました ttps://github.com/search?q=repo%3Achromium%2Fchromium%20tab%20search&type=code タブを開いた時の挙動などはTypescriptで書かれているようでした ttps://github.com/chromium/chromium/blob/cd5fe35a69d697dd48ad34d5670d090afcdc57be/chrome/browser/resources/tab_search/app.ts#L560 既存のアプリにc/c++で手軽にタイトルバーにボタンをつけてポップアップウィンドウが開けてそこでボタンなどを選択できるような方法を知っていますか? LoadLibraryに渡されたlpLibFileName引数をどうにか呼ばれたdllmainから取得する事って出来ないかな 32bitならスタックフレーム遡ってLdrLoadDllを呼んだところの第3引数のスタックのUNICODE_STRINGから手に入れる事に成功したが 64bitだとfastcallになっちゃって第4引数まではレジスタ渡しされるからこの手法も通用しなくて詰んだ kernel32やntdllのアセンブラ決め打って取得することは出来るだろうけどそこまではしたくない ちなみになぜGetModuleFileNameではダメかというとハードリンクやシンボリックリンクのときにある条件下においてlpLibFileNameとGetModuleFileNameで一致しないケースが出てくるため >>643 その >ある条件下 で TCHAR PathBuffer[BUFFSIZE]; GetMappedFileName (GetCurrentProcess(), (void *)hModule_DLL, PathBuffer, BUFFSIZE); で、lpLibFileNameと同じパス(NT形式)が返ってくる?それともエラー? 試してないので結果を教えて >>644 GetMappedFileNameだとリンク先の実体ファイル名が返ってきた ある条件下というのは既に同じリンク先のdllがロード済みの場合に違う名前のリンクからロードしようとすると同一の物と判定され先客の方のhModuleが帰ってくるためGetModuleFileNameも先にロードしたほうの名前になる C:\mod.dll ← 実体 C:\link0.dll ← シンボリックリンク C:\link1.dll ← シンボリックリンク 最初にC:\link0.dllをLoadLibraryした場合、以降C:\link1.dllをロードしGetModuleFileNameをしてもC:\link0.dllが帰ってくる GetMappedFileNameだと常にC:\mod.dllだった >>645 確認ありがとう、参考になった こみ入った環境なんだね 所望の動作でなくて残念だけど、他の手段に心当たりがない... pe iat import address table 辺りを弄れば 鶏卵かもしらんけど load されたときの名前からパラメータ参照ファイルな .ini ファイルの名を変えたいって感じなのかな? >>645 のケースだと C:\link0.dll でロードした場合には C:\link0.ini を参照し 以降 C:\link1.dllをロードした場合には C:\link1.ini を参照したい と この場合 単に同じ実体でリンクカウントが1増えるだけであっても区別したい ということか DLLはメモリに直接ロードする方法もあるから 不正を正したいって意図なら無力だよ 1. FindFirstFileでリンクか実体かを判定 2. VirtualAllocExで実行可領域のメモリを確保 3. ReadFileでDLLを読み込む 4. PEヘッダのIMAGE_OPTIONAL_HEADER64.ImageBase+IMAGE_SECTION_HEADER.VirtualAddressに各セクションをコピー 5. DLL内のImportLibraryを同じ手順で再帰的にロード 6. DLL_PROCESS_ATTACHとDLL_THREAD_ATTACHでDllMain呼び出し Win32APIのGUIに著作権ってある? 自分用ならまぁ好きにしたらって程度だと思うけど ボタンとか目コピで丸パクリしてアプリケーションとして配布したらダメなのかな 腐ったバナナの皮ですらアートとして認められるからな 許諾なしなら著作持ってる奴次第 read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる