Win32API質問箱 Build123©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
Win32APIについての質問はこちらへどうぞ。
■注意
・質問する前にMSDNライブラリやPlatformSDK、Google等で検索しましょう。
・日本語版MSDN Online Libraryは不完全です。
英語版( http://msdn.microsoft.com/en-us/library/ )の利用推奨。
・APIフックなど高度な事をしたい場合はできるだけAdvenced Windowsを読みましょう。
・言語特有の問題やIDE、MFCやVCLなどの質問はそれぞれの言語や開発環境スレで
■過去スレ
Win32API質問箱 Build122
http://echo.2ch.net/test/read.cgi/tech/1451988219/ "EDIT"にはSS_CENTERは使えないよ。EDITにはES_...スタイルを使う。 >>547
とりあえずコントロール毎に指定フラグが違う事を指摘しておく >>547
マルチバイト文字列が上手くいかないなら"AAAA"のようにシングルバイト文字列で試してみればいいじゃないか。 >>547
WM_SETFONTを使って、フォントを関連付けしてみたらどうだい? SS_CENTERがES_ENDELIPSISとして解釈されたんだろうな。
【今日の教訓】
EDITコントロールには、ES_で始まるスタイルを使え。SS_はEDITには使うな。 ごめん、ES_ENDELIPSISというスタイルはなかった。SS_CENTERの代わりにES_CENTERを指定すればいい。 そりゃ特定のコントロールに対するものだからさ。
あとSS_CENTERもES_CENTERも winuser.h で 0x01L と定義されている。
例えば共通の定義 XX_CENTER 0x01L としていた場合、
EDITコントロールの仕様変更でXX_CENTER 0x02L としたくても
STATICコントロールで同じ意義を使っているため変えることが出来ないだろ。
もし定義を変えた場合、STATICコントロールで0x02L というのは別の意味を持っている(かもしれない)ので動作がおかしくなる。
だから意味は同じでも“値”としては別のものとして扱う(定義する)。 じゃー将来SS_CENTERが別の値に変更されても安心だね 変えたらひどいことになるけどなw
本音と建前みたいなもんでCの欠点だな。後発言語はそういうとこカバーされてる(のもある) モーダルダイアログをメインの親とし、その後動的にサブメニューを表示する仕組みがあります。
サブメニュー表示中も親側の操作を可能とするため、サブメニューはモードレスとしていますが、
TABなどのキー入力が効きません。
辛うじて、初期フォーカスがあるボタンのみスペースキーを受け付けます。
マウス操作は問題ありません。
原因としてはサブメニューのキー処理をする IsDialogMessage を含むメッセージループが必要
なんだろうと思いますが、こういう場合の定石というのはあるのでしょうか?
思い付く実装は以下2パターンです。
その1
親もモードレスとし、親のメッセージループ中にサブメニューのメッセージも処理する仕組みを入れる。
その2
サブメニュー表示後に別スレッドを立ち上げ、そこでサブメニューのメッセージループを回す。
普通はこうだよ。とか他の方法などありましたらお願いします。 ちょっと語弊がありましたので訂正です。
ここで言う「サブメニュー」とは、CreateMenu などで作られる一般的に言うメニューではなく、
単なるポップアップスタイルのタイトルなしダイアログのことです。
CreateDialog で画面を作っています。
勝手に言葉を作ってすみません。 2つウインドウがあって、1つはメインウインドウ、もう1つはメニューウインドウ
メインウインドウにキーフォーカスがあるとメニューウインドウでキー操作できず、メニューウインドウにフォーカスがあるとメインウインドウでキー操作できない
メッセージを適宜流せばいいんじゃないか? フォーカスはそれがあるウィンドウで処理できるようなUIを考えています。
ユーザーがメインウィンドウにフォーカスを(マウスなどで)移せば、
以降はそのウィンドウでキーボード操作ができればいいです。その逆も然り。
適宜メッセージを流すにしても、結局どこでメッセージループを回すかという
話になるのではと思うのですが、違うのでしょうか? >>562
フォーカスを移してキーボード操作なんて危険なことを平気でやろうとする人はWin32APIなんて使わない方が良いんじゃね?
普通はフォーカスを移そうとしているオブジェクトにフォーカスを移す移さない関係なく文字列送信するもんじゃないの?
キーボード操作中にユーザーが別のウィンドウをクリックした場合とか考えないの? >>562
難しく考えるよりも、例えば、MVCベースで考えて設計したらいいんじゃねーの?
オブジェクト指向で設計するのもいいし、データ処理ありきで設計するのもあり、やりやすいように作ればいいよ。 >>566
なんで何も理解できていないのに無理に話に入ろうとするの? Windows 10 Creators Update入れたら
DrawTextで大きめのフォントの描画が異常に遅くなった。
高DPI未対応のアプリは見捨ててGDIはシンプルに動いてほしい。 >>561
>メッセージを適宜
それが質問内容でしょうよ。
>>566
タブコンに子ウィンドウ貼り付けて画面切り替えやキー入力受付なんて
日常茶飯事なのになにとち狂ったこと言ってるんだよ。
>>572
ほんとそう。
自分の知ってる単語を並べただけだわな。 Win32APIの後継でc++/cliじゃないライブラリってないのかね? win32apiはオンリーワンで現役なので後継ってもんがそもそもなし
.netはラッパーライブラリ、cliは言語仕様
>>574の求めてる物の意味が分からん
UWPでも触ってろと言えばいいのか? しいて言えばQtじゃね?
Qtのアプリって結構あるよね >>574
ライブラリってかAPIはユニバーサルwinのがそれじゃないの? >>574
Windows API
後継っつーか名前が変わっただけだが Windows10S では Win32/.net アプリは動かないだと。
UWPに変換すれば行けるらしいが、もうおしまいか? Windows10Sが相手にされなくて終わるだけ。 お前らが相手にされてないじゃん
おっさんしかいないだろうこのスレ 今回のターゲット層はメインストリームじゃないから
既存のアプリが使えなくても不満は少ないと踏んでるんだろう
まあWindowsRTみたいに核爆死はしないんじゃないか
MSもそんなに数を出荷しないだろうから
もう一度WindowsRTをSurfaceやらに載せることを夢見ているのなら
やはりもう一度爆死するだろう 教育用途だっけ
今時のキッズは学校支給タブレットの制限外してゲームしてるらしいからその点ではいいかもな あるプログラムで使用中のGDIオブジェクトの個数を数える方法はありますか? GetGuiResources(hProcess, GR_GDIOBJECTS) >>588
GetGuiResources
GR_GDIOBJECTS(0) Return the count of GDI objects.
ってあるし。 特定のアプリケーションがハング状態になってるかを判断する方法ありませんか?
.netではRespondingプロパティで判断できるようですがwin32apiでやりたいので >>600
これ使ってDoS攻撃みたいなこと出来るんかな 最近のアプリに多い、重い処理は別スレッドで実行してGUIが固まらないようにしてる場合は役に立たないかな >>604
それは「重い処理のときにハングアップしているように見える」というだけの話で、
そういうレベルでの意味ならマルチスレッド化によって役には立たない。
でもそういうマルチスレッド化したソフトウェアでも
画面描画の時の不具合などでハングアップすることもあるわけで役に立たないということはないよ。 >>605
バグでずっと重い処理が終わらない場合を想定してた。ウィンドウメッセージは処理されるものの、事実上のハング。
確かに全く役に立たないわけではないね。 ウィンドウがわかるならIsHungAppWindowってのがある >>606
動画の変換みたいに純粋に時間がかかる場合とか、ユーザーのクリック待ちとかもあるから、判断はできんだろうな 止めようとしても停まらないもの?
WindowsUpdateかな? >>609
ネットワーク切れてからのタイムアウトも異常に遅いんだよな まだ見放されてないぞ
【IT】マイクロソフト、サポート切れOS「Windows 8、Windows XP、Windows Server 2003」にも修正ソフト提供
asahi.2ch.net
test/read.cgi/newsplus/1494723803 質問ささてください
構造体AをGlobalAllocで領域を確保して値を入れた後、構造体BをGlobalAllocで確保すると、構造体Aのメンバであるポインタのアドレスが変わってしまうのですが何が原因なのでしょうか? あるプロセスのメモリ情報のリージョンサイズや属性を調べるにはどのAPIを使えばいいですか? >>612
Windowsは働き者の賢いOSだからなぁ >>612
GlobalAllocじゃなくて自分で書き換えてるんでしょ >>612
GMEM_FIXEDを指定していないGlobalAllocでロックカウントが0の場合はメモリの再配置が起きる
GlobalLockとGlobalUnlockの間なら
「構造体Aのメンバであるポインタのアドレス」は変わることがないけど
GlobalUnlockを呼び出しロックを解除した場合は再配置される可能性がある 皆様レスありがとうございます
>>612
構造体BのGlobalAllocをコメントアウトすれば問題なく動くのでこれが原因なのはたぶん間違いないです
>>617
構造体A自体のLockやFIXは試しましたがダメでした。構造体Aは領域確保後にwinAPIに渡して値を格納してもらうのですが格納後にメンバ全ての固定が必要なのでしょうか?
ともあれメモリ再配置が原因なのですね。ありがとうございました。この方向でもう少し試してみます。 ソースコードにイージーミスがある可能性の方がクッソ高いと思う >>618
そもそもの使い方が間違っているんじゃないか?
>構造体Aは領域確保後にwinAPIに渡して
そのwinAPIは何?
というかなぜ隠す必要があるのか 構造体A、もしくはその近くのメモリ確保量が足りていないような気がする
スタック破壊、または、メモリ内容破壊では? すみません。自分がC++素人でメモリ周り疎いのでよくあるトラブルかなと思い、動作確認できている部分は抽象的に書きました。イージーミスの可能性はかなりあります。
ソースが手元にないのですが、具体的にはこのような処理をしています。スマホから書いたので文法ミスあるかもしれません。
メイン処理
DWOR count=0;
LPBYTE pStructA = (LPBYTE)GlobalAlloc(GHND,sizeof(0));
GetPrinterInfo(pStructA,&count);//自作関数 pStructAに構造体格納
/*ここでブレーク張ってpStructAのpNameのアドレスが正しい文字列指してるのは確認済み*/
PStructB pStructB = (PStructB)GlobalAlloc(GHND,sizeof(StructB)*count);
/*ここで改めてpNameを取得しようとするとpNameのアドレスがpStructBを確保する前と変わっている。元の文字列データは以前として前のアドレス上に存在してることは確認済み。pStructA自体のアドレスは変わっていない
*/
for(i=0 ;i<count;i++){
LPTSTR name= (((PRINTER_INFO_1*)pStructA)+count)->pName;
}
〜〜〜
自作関数 (動作確認済み)
DWORD GetPrinterInfo(LPBYTE pStructA, LPDWORD count){
DWORD result=0;
DWORD pNeeded=0;
//必要サイズ取得
EnumPrinter(PRINTER_ENUM_LOCAL,NULL,1,NULL,pdw
&pNeeded,count);
//必要サイズ再確保
Global ReAlloc(pStructA,pNeeded,GHND);
//ここでPRINTER_INFO_1構造体をpStructAに格納
EnumPrinter(PRINTER_ENUM_LOCAL,NULL,1,pStructA,pdw
pNeeded,count);
return result;
} GlobalAllocの戻り値のハンドルを直接キャストしてポインタに代入したら駄目だろ
ハンドルを引数としてGlobalLockを呼び出して、その戻り値をキャストしてポインタに代入しろ p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
HeapFree(GetProcessHeap(), 0, p);
でうまくやってるよ,GlobalAlloc は win3.1 の仕様を下敷きにしているので使いにくいよ >>625
関数の仕様ぐらい確認しろといいたい
https://msdn.microsoft.com/ja-jp/library/cc430065.aspx
GMEM_FIXEDを指定していないGlobalAllocはメモリハンドルを返す
アドレスではなくハンドルであり、このハンドルをGlobalLockに渡すことでメモリアドレスを取得できる
メイン処理
DWORD count=0;
HGLOBAL gm = GlobalAlloc(GHND,sizeof(0));
GetPrinterInfo(gm,&count);
LPBYTE pStructA = (LPBYTE)GlobalLock(gm);
for(i=0 ;i<count;i++){
LPTSTR name= ((PRINTER_INFO_1*)pStructA)[i].pName;
}
〜〜〜
DWORD GetPrinterInfo(HGLOBAL gm, LPDWORD count){
DWORD dwSize;
DWORD result=0;
DWORD pNeeded=0;
EnumPrinter(PRINTER_ENUM_LOCAL,NULL,1,NULL,0,&pNeeded,count);
Global ReAlloc(gm,pNeeded,GHND);
dwSize = GlobalSize(gm);
LPBYTE pStructA = (LPBYTE)GlobalLock(gm);
EnumPrinter(PRINTER_ENUM_LOCAL,NULL,1,pStructA,dwSize,&pNeeded,count);
GlobalUnlock(gm);
return result;
} GMEM_MOVEABLE
移動可能メモリを割り当てます。Win32 環境では、物理メモリ内でメモリブロックが移動されることは決してありませんが、既定のヒープ内で移動することは可能です。
戻り値は、メモリオブジェクトのハンドルです。このハンドルをポインタへ変換するには、GlobalLock 関数を使います。
この値を GMEM_FIXED フラグと組み合わせることはできません。
Win32では移動することがないあるよって言ってるし、GPTRフラグを使うか、メモリ確保をmallocなりに置き換えたほうが良いね
EnumPrintersに渡すバッファのポインタは別になんでも良いみたいだし GlobalAllocはクリップボード弄る時くらいでいいよ こうゆう奴がプロジェクトにいると、デバックでは動くがリリースでは動かない
プログラムとか出来上がるんだろうな。。。
(もちろん、リリース+デバック情報埋込なら動く最悪のパターン) mallocでも、newでも好きなのつかったらいいんじゃね? みなさま本当にありがとうございました。
メモリ確保の方法に関しては古いのはなんとなくわかってるのですが、意見できる程知識がないのが実情です……
ともあれ解決方法の兆しが見えたので頑張ってみます。
>>634
耳が痛いですが自分も本当にそう思います……個人的には勉強になるのでいいんですが……
リリース気をつけておきます ※未承認広告※
Win32メッセージクラッカー簡単入力。
MsgCrack
https://github.com/katahiromz/MsgCrack 皆さんは、ダイアログの HWND に対し SetWindowLongPtr, GetWindowLongPtr を使用する場合
GWLP_USERDATA と DWLP_USER をどのように使い分けていますか? 使い分けもなにも
get してから & とか | とかして set してる エディットボックスにES_MULTILINEを付けると
Ctrl+Aですべて選択ができなくなってしまうのだけど、
これはなにか技術的な理由があってのことですか?
それとも、昔から修正されていないだけのバグですか? 642の追記ですが、ES_MULTILINEだけでなく、ES_READONLYを付けたときも、
同じようにCtrl+Aが効かなくなるようです。 >>644
つまり、ES_MULTILINEやES_READONLYはCtrl+Aに対応すべき状態ではない
というような技術的な理由があるわけではなく、
単にマイクロソフトが修正していない昔からのバグで、
サブクラス化などで対応しても問題ないものなんですよね? ctrl+aが全選択という統一ルールがないとかなんとか >>646
エディットボックスが常にCtrl+Aを扱っていないなら納得するんですが、
ES_MULTILINEやES_READONLYが付いているときだけ効かなくなるんです。 >>647
挙動としては認識通り
技術的な問題ではないのでサブクラスなりインスタンスなりのKeyDownイベントでSelectAll()して構わない
普通はついでにCopy()やCut()のショートカットキー処理もつけておく ■ このスレッドは過去ログ倉庫に格納されています