Win32API質問箱 Build126

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2020/05/01(金) 22:16:51.96ID:ZJ42fMZB
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/
2021/06/18(金) 20:14:25.45ID:Y3n+d/Ne
ATLはオブジェクトのアドレスだったような
613609
垢版 |
2021/06/19(土) 01:33:45.59ID:zlIXB2NK
ご回答くださった方々、ありがとうございます。
__func__ これだ、と思ったのですが、いま使用しているコンパイラが相当古く、
この機能をサポートしていないようです。何かうまい方法がないかもう少し考えてみます。

>>612
自分もオブジェクトのアドレスを利用できないかと考えていたのですが、インスタンスごとに
アドレスが異なると困るのではと思い、保留していました。
2021/06/19(土) 05:54:37.84ID:IUR6A6FI
uid、guid生成すんのがトレンド
2021/06/19(土) 13:13:08.67ID:tbYH3ICf
コンストラクタの呼び出し位置で __FILE__と__LINE__を使った文字列をセットするとか
616609
垢版 |
2021/06/19(土) 15:58:26.49ID:zlIXB2NK
>>614-615
ありがとうございます。
なるほど! __FILE__, __LINE__ の組み合わせは盲点でした。
これなら確かに、オブジェクトとウィンドウクラスを1対1で対応させることができますね。
少なくとも当座はこれでしのげます。
uid、guid 案もありがとうございます。
知識不足のため、勉強してから考えてみたいと思います。
2021/06/19(土) 16:18:13.72ID:BH9bYKW9
ウインドウクラス名は文字列の他にATOMでも指定できる
ATOMはRegisterClass()が返す
2021/07/09(金) 07:17:28.46ID:Qg7nE9lI
dllmainの最初の引数のHMODULEっていうかハンドルと同じ値を取得するwin32apiある?

ライブラリ作ってるけど、dllmain自体をライブラリに含めたくないから困ってる。

dllmainからHMODULEをライブラリに渡せ
みたいな変な規則も出来れば避けたい...
2021/07/09(金) 07:19:48.14ID:If26C/4W
GetModuleHandle(NULL)をキャストしる
2021/07/09(金) 07:50:25.45ID:Qg7nE9lI
GetModuleHandleのNULLは大元の実行ファイルのパス。
そうじゃなくて.dllのパスが欲しい。
その際dllmainの第一引数を使わない形で欲しい。
2021/07/09(金) 08:17:41.20ID:r/5b40UG
んでリンカーでエントリーポイントを自前のにしつつ
コンパイラのスタートアップに渡す過程で hInst をくすねるしかないんじゃないの?
622620
垢版 |
2021/07/09(金) 08:53:28.23ID:Qg7nE9lI
定義関数自身を渡しつつ、リファレンスカウンタを増やすのを回避する以下の形でいけるっぽい。
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;
}
2021/07/09(金) 11:00:40.24ID:r/5b40UG
そのライブラリを利用して
dll を記述するときは dll 自身を指して
アプリケーションを記述するときは実行ファイル自身を指すと

(GetModuleHandle() は、常に実行ファイルを指す)
2021/07/09(金) 12:53:16.14ID:If26C/4W
Module32First でも使えば〜
2021/07/09(金) 16:42:11.88ID:egaI+P/a
>>618
DLLは、アプリと同じ仮想アドレス空間を共有しており、HMODULEの値は、
DLLの PE イメージの先頭アドレスだと聞いている。
そして、DLLは単なる関数の集まりに過ぎないので、「現在のDLL」という
概念が存在しない。
dllmain が呼び出されて、OSに戻るまでの間の時間、現在どの dllmain が呼び出されているか、
という情報なら OSはどこかに持っているはずではあるが。
なお、DLLの関数群は、通常、dllmain が呼び出されている間以外に使うことが原則。
2021/07/10(土) 05:25:42.40ID:fmB/UGP2
dllは現在実行中のdllという概念はあるのでは。
あるからこそ、c++/cliでは簡単かつ確実なものとして提供されてるわけで。
2021/07/10(土) 05:59:03.94ID:fmB/UGP2
あと、現在実行中のニーモニックのアドレスより若い直近アドレスに位置するモジュールのエントリーアドレスであればそれが求めるものだし。
620は関数定義が属するdllのハンドルを得る関数になってるから、実用上問題なく機能するよね。
2021/07/10(土) 06:50:44.17ID:JLp3Oijw
そもそもDllMainのHMODULEを使わないって縛りプレイでのお話でおすし
2021/07/10(土) 09:10:30.89ID:e+Cu97LZ
>>626
そういう概念は無い。
dllmain() は、DLL が最初にロードされたとき、スレッドが開始するとき、
及び、それらの終了する時に呼び出されるエントリ関数に過ぎない。
2021/07/10(土) 09:18:08.53ID:CnbTxKRZ
>>618
> ライブラリ作ってるけど、dllmain自体をライブラリに含めたくないから困ってる。

そういのだとリンカーとかの話で、APIでどーとかってのとはまた違うような
2021/07/10(土) 09:39:49.89ID:e+Cu97LZ
>>629
[補足]
「現在ロード中で使用中の DLL」
という概念ならある。
2021/07/10(土) 09:41:14.25ID:e+Cu97LZ
>>621
[補足2]
2つ以上のDLLを使用中の場合は、その内のどのDLLのどの関数が今まさに「実行中」か
どうかは、OSレベルでは管理されてないという意味で言っている。
2021/07/10(土) 09:41:47.91ID:e+Cu97LZ
>>632
>>631 へのアンカーミスだった。スマン。
2021/07/10(土) 09:43:15.11ID:MJuwQyYP
tool help 32
2021/07/10(土) 11:50:04.86ID:fmB/UGP2
いや実行中のステップがどのdllかという概念はあるよ。
あるからデバッガでも今の瞬間実行中のステップがどの.dllのどのアドレスかまでわかってるわけで。
2021/07/10(土) 11:56:56.14ID:6bm+w6Lu
>>635
それをOSが管理してるか?って話だろ
2021/07/10(土) 12:01:47.23ID:fmB/UGP2
各々dllのベースアドレスは管理してるんだから、管理してるだろ。
管理してるかはdllは解放されるんだろ?
ベースアドレスからファイル名が辿れるから何のファイルか解るようになってるんやないか。
だからぶっ飛ぶとシステムログに飛んだdll名が明記されるやないか。
2021/07/10(土) 13:28:51.32ID:nAGZi/ZP
本当に飛躍した話が好きだよなおまえ達は
2021/07/10(土) 13:41:35.94ID:fmB/UGP2
GetModuleHandleExの仕様をみればOSの管理下にあるのわかるじゃん。

2番目の引数には。モジュールのパスでもよいが、
「モジュール内の任意のアドレス」でもいいわけ。
即ち今プログラムでましに実行中位置であるEIPレジスタやRIPレジスタの値から
dllなりexeなりのハンドルがとれると書いてあるわけで。
もちろんハンドルがとれるからファイルのパスもわかる。

管理下になかったらどうやって取れるんだってのw
2021/07/10(土) 14:24:30.76ID:aRchcoDj
ReactOSでGetModuleHandleExWをたどってみると次のようになる:

https://github.com/reactos/reactos/blob/master/dll/win32/kernel32/client/loader.c#L866
https://github.com/reactos/reactos/blob/master/dll/win32/kernel32/client/loader.c#L716
https://github.com/reactos/reactos/blob/master/dll/win32/kernel32/client/loader.c#L767
https://github.com/reactos/reactos/blob/20c1da7963debb69a46cf9f19f3e4c5e504c7fc9/ntoskrnl/rtl/libsupp.c#L34
https://github.com/reactos/reactos/blob/3fa57b8ff7fcee47b8e2ed869aecaf4515603f3f/ntoskrnl/ke/bug.c#L41

PLDR_DATA_TABLE_ENTRY構造体でプロセスの空間を保持しているようだ。
2021/07/10(土) 15:12:39.28ID:fOJ6OsHP
>>637
> 各々dllのベースアドレスは管理してるんだから、管理してるだろ。
それは
>> 「現在ロード中で使用中の DLL」
2021/07/10(土) 15:26:13.52ID:fmB/UGP2
でも結局CPUの命令アドレスからdll名を求められるから、
今CPUが実行中のdllやexeはOSが管理してるし、それ用のwin32apiも提供されている、であってるやん。
2021/07/10(土) 15:45:03.11ID:iYY30g0K
どこを実行中かをOSが管理してるなら、暴走なんてせんわな
デバッガはbreakしたらやってるだけ
2021/07/10(土) 16:12:20.61ID:6bm+w6Lu
>>642
dllを実行中かなんて管理してないぞ
単にスタックの戻りアドレスから.dll検索してログに書き込んでるだけ
2021/07/10(土) 16:44:08.48ID:fmB/UGP2
プロセス単位でexeやdllのアドレスを簡易的に言えば配列のように保持してて
あとはEIPが配列のインデックスであるかのように実行時に動くだけだから管理できてるじゃん。

indexに幅があるってだけでしょ。
2021/07/10(土) 17:41:11.37ID:fOJ6OsHP
>>645
OSはEIPを管理なんてしてないぞ
そもそもぶっ飛んだ時に関数レベルのスタックトレースができるからと言ってOSがどの関数を実行してるかを管理してるとでも言うのか?
2021/07/10(土) 17:43:28.93ID:plgO0oJb
激重OSになりそう
2021/07/10(土) 18:58:44.17ID:fmB/UGP2
いったいいつ関数の話になったんだ。
EIPからいつでもモジュールを辿れる形でプロセス情報を保持してるから管理されてると言ってるんだが。

プロセス情報を保持してないなら管理してないと言えるが。
2021/07/10(土) 19:18:42.88ID:fmB/UGP2
管理されてるを監視してるに勝手に脳内で置き換えてないやろな?
2021/07/11(日) 00:19:00.34ID:5nx6GB9W
でそれを取得するAPIは?
2021/07/11(日) 03:01:15.31ID:OgOa7vqd
管理されているというより、EIPアドレスから逆算しているという感じだね。
実行中のマシン語の命令のアドレスが分かれば、リンク時のマップファイルのような
情報があれば、どの関数の中のマシン語かまで分かるから。
2021/07/11(日) 03:07:37.40ID:OgOa7vqd
どの人がどこにいるかを国は普段は追跡してないけど、科学捜査すればどこにいるか
分かることが多いと言う意味で、「管理はしてなくても見抜くことは出来る」
のと同様の事。
2021/07/11(日) 03:11:46.75ID:OgOa7vqd
>>649
各DLLがロードされている場所のアドレス範囲とEIPさえあれば、そりゃ、どのDLL
にいるかは分かるけれど、それは管理とは言わないと思うな。
マシン語で、jmp アドレス、call アドレス で、1クロックですぐに EIP = アドレス
になるが、それをOSはいちいち追跡も管理も全くしていない。だから、
現在どのDLLの関数を実行中かをOSは情報としては持ってない。
ところが、EIPの値からどのDLLの中を実行中かを「逆算」することが可能と言うだけ。
2021/07/11(日) 03:17:09.08ID:OgOa7vqd
プログラミングの世界で「管理」というのは、
struct SomeInfo {
 int curDllIndex; // 現在実行中のDLLのインデックス番号(0-)
};
のようなデータ構造があり、idx1 という番号の DLL の中の関数を呼び出すときに、
プログラムで curDllIndex = idx1 にちゃんと書き込む、ということをイメージする。
このような意味での書き込みは行われてない。
2021/07/11(日) 03:24:26.40ID:OgOa7vqd
OSに管理されているのであれば、idx1 番の DLLから、main モジュールの関数 f()が
コールバックされたような場合でも、どのDLLから呼び出されたかまで分かるはずだが、
現実にはEIPは、f()の中をポイントしているから EIP だけからは、idx1 を逆算する
ことは不可能。
デバッガが出来てしまうのは、デバッグしやすい様にコンパイラが
「スタックフレーム」という構造が出来るようなコードをわざと作っているから。
その構造によれば、スタックとEBPの値で呼び出しもとの関数の履歴を全て辿って
いける。
しかしこれは、OSが管理しているのではなく、デバッグ版ではそのようなコードを
コンパイラが生成しているからに過ぎない。
リリース版では効率向上のためスタックフレームが省略されることもあり、その
場合は呼び出しもとの関数が辿れなくなるので idx1 という番号を算出することは
原則的には出来なくなる。
2021/07/11(日) 03:33:02.64ID:OgOa7vqd
>>655
[補足]
スタックフレームは、「ユーザーランド」のアドレス空間に構成された構造で、
OSが「管理」する「システムランド」のアドレス空間にはない。
前者はプログラムに誤りが有ると壊れることがあるし、コンパイラのオプション次第
で省略されることもあるから、いつでも存在するわけでも無いし、いつでも正しい
訳でもない。
その意味で、OSの管理する構造ではない。
2021/07/11(日) 03:48:47.46ID:NwP/aFzk
Tool Help Library ぐらいは調べて
から書きたまえ。
2021/07/11(日) 07:22:23.17ID:k3ZSGeVZ
>>657
オタクが調べて書けばいいんじゃね?
何を書きたいのか知らんけどw
2021/07/11(日) 09:13:47.20ID:NwP/aFzk
とっくに書いてるよばーか
2021/07/11(日) 09:20:59.49ID:LL6sPKEi
「管理」の定義が独り歩きしているがもともとは>>629-632だろ?
その意味では「管理」されているでいいんじゃね?
2021/07/11(日) 10:40:25.91ID:cuQ6hQba
>>659
どこに書いてあるのかレス番示して引用してみ
どうせ逃げるなら速い目に頼むw
2021/07/11(日) 10:42:50.54ID:cuQ6hQba
>>660
それに対する>>635がおかしいって言われてるんだろ
2021/07/11(日) 10:50:14.49ID:f8Vvx+nx
これは話をループさせる手段なのか?w
2021/07/11(日) 11:20:11.96ID:zTx2mwKY
「Hacking: 美しき策謀 」ぐらいは読んでこいよ
2021/07/11(日) 11:49:37.25ID:OgOa7vqd
本当に管理されていると言うのなら、別のlibで定義されている
HMODULE get_this_dll_module();
という関数によって、あらゆるDLLのHMODULEを取得できるようになるはずで
あるが、この関数は、スタックフレームを前提にしない限りは基本的に
作ることが出来ない。なぜなら
void get_this_dll_module() {
 // ここの EIP の値は、呼び出しもとの DLL のものとは違っている。
}
からである。
2021/07/11(日) 11:51:10.61ID:OgOa7vqd
>>665
誤: void get_this_dll_module()
正: HMODULE get_this_dll_module()

EIPのアドレスは、簡単に変わりうるものなのだ。
667デフォルトの名無しさん
垢版 |
2021/07/13(火) 12:38:32.06ID:WUJYnH4r
だらだらしてるので
3行でまとめてくれ
2021/07/13(火) 12:47:15.46ID:oy1AsII3
>>667
現在の関数からその関数が格納されているDLLのパスまで取得できる情報があることを
OSが管理していると呼ぶかどうかで
外野がうんこの投げ合いをしている
2021/07/13(火) 13:19:09.51ID:bYykchBX
そういうのは動物園でやれよ
2021/07/13(火) 13:50:43.04ID:EtxXgsUj
無駄な議論ではなく、質問者が、現在実行中の関数の所属する
DLLを正確に取得する方法があると思い込んでいた可能性があるので
大事な指摘だった可能性がある。
結論から言えば、安定してそれを取得する方法は無い。
2021/07/13(火) 14:46:12.78ID:imApokgP
質問者は普通に安定した方法で自己解決していったな
2021/07/13(火) 16:28:34.84ID:NGIJbx4Y
get_this_dll_moduleてなんなんってぐぐったら
このスレが引っかかってわろた
脳内の関数だったか
2021/07/13(火) 17:47:39.31ID:QuGmZAoV
未解決のせいで盛り上がってたのかと思ったら>>622で解決してたのか
2021/07/14(水) 20:59:18.35ID:bf5Y3F+J
>>620
他のこと調べてたら見つけたけど__ImageBaseって変数のアドレスがまさに目的そのものっぽいわね

https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
2021/07/14(水) 21:06:59.94ID:v50kRHgT
「D:\aaaa\bbbb」などの、ファイルやフォルダのパス名から、
そこがCDやDVDなどの光学ドライブかを判定する仕組みはありますか?
2021/07/14(水) 21:11:04.17ID:DOxWmp+E
GetLogicalDriveStringsかな
2021/07/14(水) 21:13:56.34ID:DOxWmp+E
途中送信ごめん

全ドライブ文字と種類がわかるから
後は比較するオレオレ関数作る感じ
2021/07/14(水) 21:15:40.83ID:DOxWmp+E
何度もごめん

種類はGetDriveTypeね
2021/07/14(水) 21:36:03.70ID:v50kRHgT
>>678
ありがとうございます。
GetDriveTypeは、"D:\"の3文字の部分しか渡せないようですが、
PathGetDriveNumberでも使えば、"D:\"の部分だけを作れそうですね。
2021/07/15(木) 01:52:58.00ID:0fB1tPL7
リッチエディットに複数行の文字列をプログラムから定期的に送って全内容を更新するプログラムを作成しています。
更新中は垂直スクロールバーで任意の行に移動できるようにしています。
コードは下記です。

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 ); // 表示を促す

これで、ある程度までの行数の文字列であれば、意図通りの挙動となるのですが、
行数が多くなってくると、動かしていたスクロールバーが一瞬一番下まで下がってから
元の位置に戻るという現象が文字列更新の度に起こります。
ただ、リッチエディット内の表示位置は、動かしていたスクロールバー位置に対応する位置のままで、
スクロールバーが一瞬一番下がる動きとは連動しません。

一体何が起こっており、どのようにすれば回避できそうでしょうか?
2021/07/15(木) 09:58:52.50ID:ux6gJq+a
もしかしてそれって32767行くらい超えてから?
682680
垢版 |
2021/07/15(木) 12:02:49.75ID:0fB1tPL7
>>681
改行文字(\n)だけの80行くらいでも発生しました。
そして>>680の内容に訂正があります。
>動かしていたスクロールバーが一瞬一番下まで下がってから
は、一番下までは下がっていませんでした。
また、下がったときはバーが長くなっており、
あたかも行数が少なくなったかのよう(エディット内の表示は意図通り)な挙動です。
さらに、以下のような性質も分かりました。

・スクロールバー位置が一番上のときは一瞬下がる症状が発生しない
・スクロールバー位置が一定より下になると一瞬下がる症状が発生しない
 ・この位置は全体行数とリッチエディットの縦幅との関係によって変わり、
  スクロールバーの長さが全体の大半を占める場合はどの位置でも発症しなくなる
2021/07/15(木) 13:08:28.58ID:ux6gJq+a
>>682
キャレットが画面外にあるか画面内にあるかで挙動は変わったりする?
2021/07/15(木) 13:18:19.61ID:dBy6yJWz
一口にリッチエディットっていってもバージョンが4種類くらいあって
それぞれ微妙に動作が違ったような気がする
685680
垢版 |
2021/07/15(木) 14:06:57.14ID:0fB1tPL7
>>683
文字列更新前にキャレットが画面内にあるか画面外にあるかで挙動に変化ありませんでした。

>>684
リッチエディットのバージョンはv2.0(UNICODE)です。
2021/07/15(木) 15:02:56.70ID:GxcfqrJG
特定プロセス(PID)のアドレス空間の情報を取得するAPIはありますか?
687デフォルトの名無しさん
垢版 |
2021/07/15(木) 15:17:12.92ID:ygp86UHP
スクロールバーの描画も同時に禁止するとか
スクロール範囲の最大値も強制的に変更してから描画再開するとか
2021/07/15(木) 15:39:38.74ID:SuupqHo1
>>685
キャレットが画面内でも外でも
おかしな症状が発生するかどうかは>>682の条件って事?
689680
垢版 |
2021/07/15(木) 16:21:18.89ID:0fB1tPL7
>>687
スクロールバーのハンドルを取得する方法が分からなかったので、
テキスト&スクロールバー位置更新時、ダイアログ全体の再描画を抑制してみましたが、
再描画がかかるタイミングでやはりスクロールバーが一瞬動きます。

スクロール範囲の最大値もテキスト更新前に控えておいた数値を、テキスト更新後に設定しましたが変わらずでした。

>>685
はい、>>682の条件です。


進展がありました。
SetWindowText()でテキスト更新をしていた部分を

SendMessage( hEdit, EM_SETSEL, 0, -1 );
SendMessage( hEdit, EM_REPLACESEL, FALSE, ( LPARAM )str );

と置き換えたところ、
スクロールバーを動かしても、その後、一瞬下に動くといったことがなくなり、
期待通りその場に留まり続けてくれました!
しかし、ダイアログのフォーカスを外した後、再度フォーカスを得ると、一番下に飛んでしまいます・・・。
惜しい・・・。

フォーカス取得の際、スクロールバー位置が更新されるものと思われますので、
そのときのウインドウメッセージを捕えて、テキスト更新時と同様にスクロールバー位置を制御すればいけるかもです。
2021/07/15(木) 16:33:06.78ID:t/RIbQSu
>SendMessage( hEdit, EM_LINESCROLL, 0, -INT_MAX ); // 表示行を一番上に移動する
>SendMessage( hEdit, EM_LINESCROLL, 0, Line ); // 表示行を、控えておいた位置に移動する
これで振動してるような気もする

フォント高さ x 行数 と クライアント領域の高さが不一致な状態で
SetWindowText() で更新したとき、クライアント領域内の先頭行側が欠けて 最終行側がきっちり見えてるんだけど

上の2行の変わりに
 SendMessage( hEdit, EM_LINESCROLL, 0, 0);
を投げると先頭行がきっちり収まる位置にきて、スクロールバーがピコピコすることもない雰囲気
2021/07/15(木) 17:34:53.12ID:SuupqHo1
>>689
ダイアログカヨ

WM_ACTIVATEが悪さしてるとかない?
2021/07/15(木) 18:00:01.33ID:P7zOCeng
WM_VSCROLL.SB_TOP使った方がいいんじゃね?
2021/07/15(木) 18:23:17.10ID:L0wYNjuD
>>680
>SendMessage( hEdit, WM_SETREDRAW, FALSE, 0 ); // 文字列更新中の状態が露呈しないよう再描画を抑制する
↑は、RichEditControl のメッセージではなく、Win32のWindow一般のものらしい。
但し、MSDNには、ListBoxで複数のアイテムを追加するときに便利だと書いてある。
質問者の実験を聞く限り、RichEditControlにのみこのメッセージを送っただけでは、
そこにくっついているスクロールバーに対しては効果が無いようだ。
2021/07/15(木) 18:45:09.69ID:L0wYNjuD
Rich Edit Control を作成する時のスタイルに
WS_VSCROLL
を付け、
ES_DISABLENOSCROLL
を付け、
ES_AUTOVSCROLL
を外すと縦スクロールバーが出るが、勝手に制御されにくくなるかも。
2021/07/15(木) 18:49:18.52ID:L0wYNjuD
WM_SETREDRAWは、ListBoxに関しては色々語られている:
https://devblogs.microsoft.com/oldnewthing/20110124-00/?p=11683
2021/07/15(木) 18:55:04.61ID:L0wYNjuD
SendMessage( hEdit, WM_SETREDRAW, FALSE, 0 );
は効果は有るにはあるが、アプリ側が自らスクロールバーを制御するようなメッセージを
Rich Edit Control に送った場合、↑の設定が無視されて、スクロールバーの描画が
起きてしまっている可能性がある。なので、
>SendMessage( hEdit, EM_LINESCROLL, 0, -INT_MAX ); // 表示行を一番上に移動する
>SendMessage( hEdit, EM_LINESCROLL, 0, Line ); // 表示行を、控えておいた位置に移動する
の部分、上の行を省いて、下の行だけにするとちらつかなくなる可能性が高い。
また、上の行の役割の代わりとして、カーソルの位置はスクロールの位置とは別に制御すると良いはず。
697680
垢版 |
2021/07/16(金) 01:36:18.95ID:iUp23Wxq
>>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だと背景がグレーになる(審美的にはリッチエディットのような白が好ましい)
・表示矩形内に文字が収まっていてもスクロールバーの枠が表示される
・表示がたまにチラツく
といった気になる点があるのですが、不安定なスクロールバーに比べたら許容範囲です。

多数のご助言をいただき、ありがとうございました。
2021/07/16(金) 01:48:03.35ID:5FJrAAJE
どうでもいいけどWin32とかの文字列の型名わかりずらすぎて嫌がらせとしか思えない
なんだよLPCTSTRってconst wchar_t*でいいだろ
2021/07/16(金) 11:06:31.00ID:rEsqDZWm
それだとLPCWSTRでは
2021/07/16(金) 11:36:36.57ID:teDb7k99
スカラ値へのポインタではなく配列先頭アドレスですよという意図は一応あるのかもしれない
701デフォルトの名無しさん
垢版 |
2021/07/16(金) 11:42:16.54ID:5FJrAAJE
>>699
はにゃ?
https://imgur.com/a/1pn6Inx
2021/07/16(金) 11:57:18.77ID:teDb7k99
UNICODE マクロが定義されていればそれはそう
2021/07/16(金) 11:58:40.86ID:wMimqxZO
Tがつく奴はUNICODEの定義の有無でwchar_tかcharに変わるから
2021/07/16(金) 13:31:01.23ID:rEsqDZWm
>>701
そもそも全部wchar_tでいいって事なら
TじゃなくてWでいい
2021/07/16(金) 14:39:23.11ID:qFBlhvM+
UNICODE対応とはいわばUTF8に対応していると思っている僕がかつて居ました
706デフォルトの名無しさん
垢版 |
2021/07/16(金) 16:32:41.77ID:6/LQ7Fle
いまどき -D_UNICODE せんやつはおらんよな?よな?
2021/07/16(金) 17:34:41.64ID:AYv25WJv
>>706
>いまどき -D_UNICODE せんやつはおらんよな?よな?

自分はここしばらくWindowsのプログラムから離れてるんで、思い違いしてるかもしれんが・・・
いまどきはWindows10のワールドワイド言語サポートを使ってアプリ内部・外部入出力ともUTF-8にするんじゃないか?
2021/07/16(金) 17:54:02.54ID:kcNPB8fl
_UNICODEはWin32APIがUTF-16版かどうかの話なんでアプリは好きにやりゃええねん
2021/07/16(金) 17:58:18.04ID:uF0JvJPV
>>707
VC付属のCライブラリがUTF-8に完全対応してない
ファイルオープンで積む
VCの対話デバッガも変数のUTF-8テキストビューに対応してない
2021/07/16(金) 18:27:58.18ID:uF0JvJPV
失礼、積むではなく詰むだった
2021/07/16(金) 19:08:27.97ID:tbXedaSH
ビジネスが破綻する大半の原因は、 ”ビジネスを始める人の大半が、真の意味での
「起業家」ではなく、 起業したい、という熱に浮かれた「職人」として働いているに過ぎない。”
という事実にあります。
「職人」によって運営されているビジネスは、ビジネスが働くのではなく、彼ら自身が毎日働くこと
によって、成り立っています。
彼らは毎日、自分がやり方を知っている仕事を一生懸命にこなしていますが、「起業家」としての
視点が無いために、成長に限界が生まれます。
そして、生計を立てるために、彼ら自身がずっと働き続けないとならないのです。

誰もが必ず陥る罠
私が見ている限り、起業熱にうなされる人たちは、必ずと言ってもよいほど誤った
「仮定」を置いてしまうようだ。実は、のちに彼らが苦難の道を歩むことになるのは、
この、「仮定」が致命的に間違っているからなのである
致命的な仮定とは・・・「事業の中心となる専門的な能力があれば、事業を経営する能力は
十分に備わっている」ということである
私がこの仮定を致命的だと書いたのは、この仮定が間違っているからにほかならない
事業の中で専門的な仕事をこなすことと、その能力を生かして事業を経営することは
全く別の問題である。高い専門能力を持つ人にとって、独立は他人の為に働くという苦痛から
解放されるということを意味していた。それにもかかわらず、前提となる「仮定」が致命的とも
いえるほど間違えているために、彼らは自由になるどころか、自分が始めた事業に苦しめ
られるようになってしまうのである
マイケルEガーバー「はじめの一歩を踏み出そう」P28~29
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況