ホーム » VC (ページ 2)
「VC」カテゴリーアーカイブ
error C2144 , C2501
ビルドしていると
--------------------Configuration: TToPA - Win32 Release--------------------
Compiling...
TToPADlg.cpp
C:\Program Files (x86)\Microsoft Visual Studio\VC98\INCLUDE\gl/gl.h(23) : error C2144: syntax error : missing ';' before type 'int'
C:\Program Files (x86)\Microsoft Visual Studio\VC98\INCLUDE\gl/gl.h(23) : error C2501: 'c' : missing storage-class or type specifiers
C:\Program Files (x86)\Microsoft Visual Studio\VC98\INCLUDE\gl/gl.h(23) : fatal error C1004: unexpected end of file found
Error executing cl.exe.
TToPA.exe - 3 error(s), 0 warning(s)
ファイルの先頭に “c” の文字が入力されてしまっていた.
デバッグしていて,何かの拍子に “c” が入ってしまったことに気づかなかった.
バックアップしてあったファイルを戻して対応.
error C2062 , C2065
先日作成した,レジストリなどのアクセスのコード.
それを使用しているコードを VC 2015 環境でビルドすると…
1>------ ビルド開始: プロジェクト:S_asZ, 構成:Debug Win32 ------
1>t:\develop\_.src\__win\ri_env.hxx(67): error C2062: 型 'bool' は不要です。
1>t:\develop\_.src\__win\ri_env.hxx(69): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(70): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(72): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(78): error C2062: 型 'bool' は不要です。
1>t:\develop\_.src\__win\ri_env.hxx(80): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(81): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(83): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(133): error C2062: 型 'bool' は不要です。
1>t:\develop\_.src\__win\ri_env.hxx(135): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(136): error C2065: 'res': 定義されていない識別子です。
1>t:\develop\_.src\__win\ri_env.hxx(138): error C2065: 'res': 定義されていない識別子です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
今まで OpenMP が動作しない状態でのビルドだったので気づかなかった.
#ifdef _OPENMP … #endif の位置が違っていた.
bool set_DW (LPCTSTR sec,LPCTSTR ent,const u_32 val) {
bool res = false ;
#ifdef _OPENMP
#pragma omp critical (RI_app_set_DW)
#endif
{
if (Use_reg) { REG_get_sec_key(sec) ; res = RI_rkey.set_DW( ent,val) ; }
else { res = :: INI_set(NameINI,sec,ent,val) ; }
}
return res ;
}
bool res = false を #ifdef の前に持ってきて対応.
error C2666: ‘get’ : 8 overloads …
次の様なコードをコンパイルすると,「error C2666: ‘get’ : 8 のオーバーロード関数があいまいです。」
{
#define SecProtectT _T("Debug")
RI_app CountP ;
RI_env CountC ;
tstring exe_title = ::Path_GetTitle(::RI_get_module_name()) ;
time_t nowTime = ::time(NULL) ;
time_t countP_ = time_t(CountP.get(SecProtectT,exe_title.c_str(),i_32(nowTime))) ;
time_t countC_ = time_t(CountC.get(SecProtectT,exe_title.c_str(),i_32(nowTime))) ;
time_t countPT = time_t(CountP.get(SecProtectT,exe_title.c_str(),i_64(nowTime))) ;
time_t countCT = time_t(CountC.get(SecProtectT,exe_title.c_str(),i_64(nowTime))) ;
}
--------------------構成: PrtctT - Win32 Debug--------------------
コンパイル中...
PrtctT.cpp
l:\document\develop\tools\_yet\_other\key2013\prtctt\prtctt.cpp(110) : error C2666: 'get' : 8 のオーバーロード関数があいまいです。(新しい機能 ; ヘルプを参照)
l:\document\develop\tools\_yet\_other\key2013\prtctt\prtctt.cpp(110) : fatal error C1903: 直前のエラーを修復できません; コンパイルを中止します。
cl.exe の実行エラー
PrtctT_d.exe - エラー 2、警告 0
次のメンバ関数を追加したことによる影響だったが,RI_app でエラーになっていないのがよくわからない.
i_32 get (c_tstring& sec,c_tstring& ent,const i_32 def) { … }
次の LPCTSTR 形式のメンバ関数を追加して対応.
i_32 get (LPCTSTR sec,LPCTSTR ent,const i_32 def) { … }
C2440: ‘return’ : cannot convert …
以前,ini や レジストリ を操作する関数を作成した.
それで,少しずつ書き換えていると…
--------------------Configuration: PrtctT - Win32 Debug--------------------
Compiling...
PrtctT.cpp
t:\develop\_.src\__win\ri_reg.hxx(383) : error C2440: 'return' : cannot convert from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
l:\document\develop\tools\_yet\_other\key2013\prtctt\prtctt.cpp(162) : see reference to function template instantiation 'int __cdecl REG_get(struct HKEY__ *,const class std::basic_string<char,struct std::char_traits<char>,class std::allocato
r<char> > &,const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,const int &)' being compiled
Error executing cl.exe.
PrtctT_d.exe - 1 error(s), 0 warning(s)
通常の関数であればうまく機能すると思うが…
関数 template は難しい.
コメントにしている部分で書き換えれば OK .
Windows C++ __argc __argv
MFC でコードを書いていて,コマンドライン引数を取りたくなった.
MFC では次の様にすれば取れるが,欲しいのは c の main に渡される argc と argv .
CString cmd_line = AfxGetApp()->m_lpCmdLine ;
検索すると次の所があった.欲しかった情報は __argc と __argv .
【 VC++ MFC 】MFC でコマンドライン引数を利用する方法
次の様なコードを書いて動作を確認.
#include <clocale>
#include <iostream>
#include <tchar.h>
#ifdef _UNICODE
#define tin wcin
#define tout wcout
#define terr wcerr
#define tlog wclog
#else
#define tin cin
#define tout cout
#define terr cerr
#define tlog clog
#endif
int _tmain (int ,TCHAR* )
{
_tsetlocale(LC_ALL,_T("")) ;
{
std::tout << __argc << std::endl ;
for (int index=0 ; index<__argc ; index++) {
std::tout << __targv[index] << std::endl ;
}
}
return 0 ;
}
_tmain が呼び出される前の mainCRTStartup の ::_setargv で設定されている.
LNK2001 _WinMain@16
VC 6 で,_MBCS から _UNICODE に変更すると,次のエラーになることがある.
--------------------Configuration: T_mtx_n - Win32 Release--------------------
Compiling resources...
Compiling...
StdAfx.cpp
Compiling...
T_mtx_n.cpp
T_mtx_nD.cpp
Generating Code...
Linking...
msvcrt.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16
c:\Temp\Test_win\T_mtex\T_mtx_n\Release.060/T_mtx_n.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
T_mtx_n.exe - 2 error(s), 0 warning(s)
C2039 , C3861 , C2665
個人的なメモです.
VC 6 プロジェクトを VC 7 以降にあげた時のエラー.
1>------ ビルド開始: プロジェクト: PLtoB, 構成: Debug Win32 ------
1>コンパイルしています...
1>PLtoBDlg.cpp
1> ...
1>t:\develop\_.src\__iwao\htmo_th.hxx(70) : error C2039: 'ToImage' : '`global namespace'' のメンバではありません。
1>t:\develop\_.src\__iwao\htmo_th.hxx(70) : error C3861: 'ToImage': 識別子が見つかりませんでした
1>t:\develop\_.src\__iwao\htmo_th.hxx(155) : error C2665: 'ToDIB' : 3 オーバーロードのどれも、すべての引数の型を変換できませんでした
1> t:\develop\_.src\__win\i_dib_fn.hxx(188): 'i_DIB ToDIB(const HBITMAP)' の可能性があります。
1> t:\develop\_.src\_afxw\i_dib_x.hxx(86): または 'i_DIB ToDIB(const MemoryDC &)'
1> 引数リスト '(Image)' を一致させようとしているとき
1> ...
1>PLtoB - エラー 3、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
Imgae.hxx を XxxDlg.h に追加.
次の場合は,MemoryDC.hxx を追加.
1>------ ビルド開始: プロジェクト: PLtoB, 構成: Debug Win32 ------
1>コンパイルしています...
1>PLtoBDlg.cpp
1> ...
1>t:\develop\_.src\__iwao\htmo_th.hxx(35) : error C2665: 'ToDIB' : 3 オーバーロードのどれも、すべての引数の型を変換できませんでした
1> t:\develop\_.src\__win\i_dib_fn.hxx(188): 'i_DIB ToDIB(const HBITMAP)' の可能性があります。
1> t:\develop\_.src\_afxw\i_dib_x.hxx(56): または 'i_DIB ToDIB(const Image &)'
1> 引数リスト '(MemoryDC)' を一致させようとしているとき
1> ...
1>PLtoB - エラー 1、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
VC 14.x での MFC のソース?
VC 2019 など最新でない VC を使用していると,MFC ソースにステップイン できなくなることがある.
大抵は,インストールされている最新の MFC の場所を指定すれば良さそう.
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.37.32822\atlmfc\include
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.37.32822\atlmfc\src\mfc
VC のアップデートがあり更新したためか,一部で「ビルド時のものと異なる」と表示されるようになった.
---------------------------
Microsoft Visual Studio
---------------------------
ソース ファイル:C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.37.32822\atlmfc\include\cstringt.h
モジュール:C:\Windows\SysWOW64\mfc140ud.dll
プロセス:[28036] GLSmth.exe
ソース ファイルがモジュールがビルドされたときのものと異なります。デバッガーでこのファイルを使用しますか?
---------------------------
はい(Y) いいえ(N)
---------------------------
角の二等分線
https://en.wikipedia.org/wiki/Bisection
wiki にあるアニメーションをコードにしたもの.
Ld2 V2_get_bisector (const Vd2& vp,const Vd2& vc,const Vd2& vn)
{
// * vp
// |
// |
// | * vcx
// | /
// | o /
// | / o
// vc * - - - - - - * vn
Vd2 vcp = (vp-vc).Normalized() ;
Vd2 vcn = (vn-vc).Normalized() ;
Vd2 vcb = (vcp+vcn)/2. ;
Vd2 vcx = vcb + vc ;
{
vcx = ::get_cross_line(vp,vn,vc,vcx) ;
}
Ld2 lbs(vc,vcx) ;
return lbs ;
}
青い円弧が,最初の 2 行の Normalized .
次の中点を求めているのは,赤い円弧の交点を結ぶ線にあたる.
二等分線を対辺?まで延長.
warning C4305:
先日次の様なコードを書いていた.塗りつぶして表示する時の色の補正.
ColorRGB colRGB = ::ColorRefToRGB(pgs1.GetColor()) ;
{
float rgbcol = colRGB.R + colRGB.G + colRGB.B ;
if (rgbcol < 0.20*3) {
if (colRGB.R < 0.20) { colRGB.R = 0.20f ; }
if (colRGB.G < 0.20) { colRGB.G = 0.20f ; }
if (colRGB.B < 0.20) { colRGB.B = 0.20f ; }
}
if (0.80*3 < rgbcol) {
if (0.80 < colRGB.R) { colRGB.R = 0.80f ; }
if (0.80 < colRGB.G) { colRGB.G = 0.80f ; }
if (0.80 < colRGB.B) { colRGB.B = 0.80f ; }
}
}
ColorRGB.R などは float で,RGB のそれぞれを 0.0 ~ 1.0 で表現したもの.
最初 if (colRGB.R < 0.25) { colRGB.R = 0.25 ; } の様にしていたが,0.2 に変更した.
すると C4305 の warning .0.2f の様にすれば良いのはわかっているが,他の値で調べてみた.
0.0 , 1.0 , 7.0 などは大丈夫だが,0.2 や 7.1 は C4305 になってしまう.
コンパイラやオプションの指定にもよると思うが,float で表現できない場合のみ warning となるのか?
VC 2022 17.6.?
先日 VS 2022 の更新版 があったのでアップデート.
個人的なツールの 3D ビューア をビルドすると,
ALYac Gen:Variant.Tedy.373496
Arcabit Trojan.Tedy.D5B2F8
BitDefender Gen:Variant.Tedy.373496
Cylance Unsafe
DeepInstinct MALICIOUS
Emsisoft Gen:Variant.Tedy.373496 (B)
eScan Gen:Variant.Tedy.373496
GData Gen:Variant.Tedy.373496
MAX Malware (ai Score=81)
McAfee Artemis!AE3A9CE560AE
McAfee-GW-Edition Artemis
Trellix (FireEye) Gen:Variant.Tedy.373496
TrendMicro-HouseCall TROJ_GEN.R002H09EQ23
VIPRE Gen:Variant.Tedy.373496
VC 2019 などでビルドしたものは問題ない.また VC 2022 更新前のものも問題なかった.
今まで VS の更新版が出てすぐにそれでビルドすることは少なかった.
テストが不十分なこともあり,リリース用は主に VC 2017 を使用している.
更新版によっては,この様なことがあるのかもしれない.
落ち着くまでしばらく時間がかかるのか?
error during ReadSymbolTable
5 年位前に作成したプロジェクトをビルドしていると,
--------------------Configuration: phpup_mb - Win32 Debug--------------------
Compiling...
ComPrj01.cpp
phpup_mb.cpp
...
Linking...
c:\Temp\HTM\phpup\phpup_mb\Debug.060\ComPrj01.obj : error : Internal error during ReadSymbolTable
ExceptionCode = C0000005
ExceptionFlags = 00000000
ExceptionAddress = 004623F2
NumberParameters = 00000002
ExceptionInformation[ 0] = 00000000
ExceptionInformation[ 1] = 0090B470
CONTEXT:
Eax = 3FFF1E64 Esp = 0019F050
Ebx = FFFF8000 Ebp = 01B834C7
Ecx = 3FFF1E64 Esi = 401F1EC0
Edx = 0094B478 Edi = 401F1EC0
Eip = 004623F2 EFlags = 00010246
SegCs = 00000023 SegDs = 0000002B
SegSs = 0000002B SegEs = 0000002B
SegFs = 00000053 SegGs = 0000002B
Dr0 = 0019F050 Dr3 = FFFF8000
Dr1 = 01B834C7 Dr6 = 3FFF1E64
Dr2 = 00000000 Dr7 = 00000000
Error executing link.exe.
Tool execution canceled by user.
exe は存在するが正しくできていないので,exe のみ削除して再度ビルド.
--------------------Configuration: phpup_mb - Win32 Debug--------------------
Linking...
LINK : LNK6004: c:\Temp\HTM\phpup\phpup_mb\Debug.060/phpup_mb.exe not found or not built by the last incremental link; performing full link
ComPrj01.obj : fatal error LNK1143: invalid or corrupt file: no symbol for comdat section 0xffff8000
Error executing link.exe.
phpup_mb.exe - 1 error(s), 0 warning(s)
obj のサイズを見ると,20 MB 位になっている.
それで思い出したのが,前にも同じ様な現象が…
LNK1143 : ファイルが無効であるか…
ソースを分割して対応.
高 DPI VC 「高い DPI 認識」
引き続きいろいろとやっているが…
異なる DPI での対応は簡単ではなさそう.
VC のプロパティで「モニターごと高い DPI 認識」としてビルドしていたが,モニタ間を移動するとうまくない.
ちゃんと対応すれば良いのだろうが,簡単ではない.
そのため exe のプロパティで「システム(拡張)」で良いと思っていたが,幾つかのバグ?(未対応)がある.
VC のプロパティで「高い DPI 認識」にしてビルドしたものの方がうまく機能している様な気がする.
左から VC 10 ,14 ,10 ,14 としたもの.
タスクマネージャで見ると,VC 10 exe は「システム」として表示される.
左側のモニタの範囲は次の様になる.
-1920 130 0 1210 100% 1920 1080 「非対応」や「モニタごと」の場合
-3840 260 0 2420 200% 3840 2160 「システム」とした exe の場合
右側は ( 0 , 0 ) – ( 3840 , 2160 ) .
GDI スケーリングの動作として,次の記述があった.
アプリケーションが 100% (96 DPI) の倍数ではないディスプレイで実行されている場合、ベクター グラフィックスとテキストは、ディスプレイの倍率より 100% 高い最初の整数倍にレンダリングされます。たとえば、アプリケーションが 225% の縮尺のディスプレイ上にある場合、ベクター グラフィックスとビットマップは 300% でレンダリングされます。その後、DWM はレンダリングされたコンテンツを 225% のスケールに縮小します。この場合、スケールダウンによりアプリケーションのあいまいさが目立ちますが、100%レンダリングされたコンテンツを単純にスケールアップするよりも見栄えが良くなります。
Improving the high-DPI experience in GDI based Desktop Apps
How to build high DPI aware native Windows desktop applications
2023/05/12
「システム(拡張)」で幾つか変な動作があったが,「高い DPI 認識」でビルドしたものであれば良さそう.
C++ メンバ関数テンプレート
.ini に対してのアクセスは関数として用意した が,今度はレジストリ.
クラスとして実装して,基本的な動作は何とかできた.
さらに .ini と同様に,文字列としてアクセスする部分を呼出す関数をテンプレートに…
と思って書き始めたが,今まで使ってなかったのか書き方がわからない.
検索すると,次の所があり参考にさせてもらった.
メンバ関数テンプレート | Programming Place Plus C++編【言語解説】 第33章
メンバー関数テンプレート
特に通常の関数テンプレートと書き方は変わらない.
template <typename T> T get ( LPCTSTR ent,const T& def) {
tstring dst = ::To_tstring(def) ;
tstring str = this->get(ent,dst.c_str()) ;
T val ;
::string_to(str.c_str(),&val) ;
return val ;
}
template <typename T> bool set ( LPCTSTR ent,const T& val) {
tstring str = ::To_tstring(val) ;
return this->set(ent,str.c_str()) ;
}
C++ 戻り値の異なる関数 template
先日からやっている .ini やレジストリにアクセスする関数.
MFC の CWinApp::GetProfileString , CWinApp::WriteProfileString にあたる部分は目途がついた.
それで,それらを呼出す部分.前に作成したものもそうだったが,型ごとにクラスの関数を定義していた.
これらをもう少し簡単にできないかと…
set の方は,特に難しい所はない(::To_tstring は,文字列に変換する関数として用意している).
template <class T> bool INI_set (LPCTSTR sec,LPCTSTR ent,const T& val)
{
tstring ini = ::INI_get_module_ini() ;
tstring str = ::To_tstring(val) ;
return ::INI_set(ini.c_str(),sec,ent,str.c_str()) ;
}
get の場合,文字列から変数に変換する方法をどうするか?
例えば,atoi や atof ,他にも 4 つの整数の文字列を RECT に変換するなど.
検索すると template で可能みたい だが…
よくわからなかったので,簡単な方法にした.
inline RECT To_RECT (LPCTSTR str)
{
RECT rect = { 0 } ;
{
v_tstring str_ary = ::String_SplitSpace(str,_T(" ,\t\r\n")) ;
if (0 < str_ary.size()) { rect.left = ::ttoi4(str_ary[0]) ; }
if (1 < str_ary.size()) { rect.top = ::ttoi4(str_ary[1]) ; }
if (2 < str_ary.size()) { rect.right = ::ttoi4(str_ary[2]) ; }
if (3 < str_ary.size()) { rect.bottom = ::ttoi4(str_ary[3]) ; }
}
return rect ;
}
inline bool string_to (LPCTSTR str,RECT* rect_) { *rect_ = ::To_RECT (str) ; return true ; }
inline bool string_to (LPCTSTR str,POINT* point) { *point = ::To_POINT(str) ; return true ; }
inline bool string_to (LPCTSTR str,SIZE* size_) { *size_ = ::To_SIZE (str) ; return true ; }
それぞれの型に合わせた関数を呼べるようになったので template に.
template <class T> T INI_get (LPCTSTR sec,LPCTSTR ent,const T& def)
{
tstring ini = ::INI_get_module_ini() ;
tstring dst = ::To_tstring(def) ;
tstring str = ::INI_get(ini.c_str(),sec,ent,dst.c_str()) ;
T val ;
::string_to(str.c_str(),&val) ;
return val ;
}
これで,次の様な使い方ができる様になる.
{
POINT point = ::POINT_set( 10, 20) ;
SIZE size_ = :: SIZE_set( 1111, 525) ;
RECT rect_ = :: RECT_set(point,size_) ;
{
::INI_set(_T("test"),_T("rect_"),rect_) ;
::INI_set(_T("test"),_T("point"),point) ;
::INI_set(_T("test"),_T("size_"),size_) ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("rect_"),rect_)) << std::endl ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("point"),point)) << std::endl ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("size_"),size_)) << std::endl ;
}
}
C++ NonCopyable
MFC を使用しないコードに書き直していて,代入できない構造体が欲しくなった.
オリジナルのコードは 20 年以上前のもので,CRegKey が簡単には使えなかった?頃.
「C++ クラス 代入できなくする」で検索.
コピー禁止を徹底させるNoncopyableクラス
More C++ Idioms/コピー禁止ミックスイン(Non-copyable Mixin)
明示的に既定された関数および削除された関数
MFC の CObject も同様と思いソースを見ると,やはり private になっている.
C++11 以降では =delete も使える.
関数のdefault/delete宣言
wiki C++11
これらを調べていて,次の所を見つけた.
旧時代のC言語を使うのはそろそろやめよう。
2016年、C言語はどう書くべきか (前編)
2016年、C言語はどう書くべきか (後編)
幾つかは既に意識しているが,Windows に依存する部分はなかなかできてない.
RegOpenKeyEx REGSAM
レジストリアクセスのコードを書き直していて,::RegOpenKeyEx の samDesired を調べてみた.
KEY_READ (0x20019) 0010 0000 0000 0001 1001
KEY_WRITE (0x20006) 0010 0000 0000 0000 0110
KEY_EXECUTE (0x20019) 0010 0000 0000 0001 1001
KEY_QUERY_VALUE (0x0001) 0000 0000 0000 0001
KEY_SET_VALUE (0x0002) 0000 0000 0000 0010
KEY_CREATE_SUB_KEY (0x0004) 0000 0000 0000 0100
KEY_ENUMERATE_SUB_KEYS (0x0008) 0000 0000 0000 1000
KEY_NOTIFY (0x0010) 0000 0000 0001 0000
KEY_CREATE_LINK (0x0020) 0000 0000 0010 0000
KEY_WOW64_64KEY (0x0100) 0000 0001 0000 0000
KEY_WOW64_32KEY (0x0200) 0000 0010 0000 0000
KEY_ALL_ACCESS (0xF003F) 1111 0000 0000 0011 1111
読み込み時,KEY_READ の方が速いなどはあるのか?それともファイルアクセスなどと同じ?
GetMonitorInfo
2002/08 に,マルチディスプレイ対応のコードを書いている.
今回,高 DPI 対応やディスプレイ位置が変わった時などのためもう一度…
ChatGPT で.
そのままでは VC 6 ではうまくビルドできなかったので,VC 8 で.
printf を使用しているので #include <cstdio> が必要.
そのまま実行すると 1920×1080 となる.
高 DPI スケール設定を「アプリケーション」とすると,3840×2160 .
2023/04/14
以前のコードを見ると,プライマリのみの情報は ::SystemParametersInfo などを使用している.
これで求められる SPI_GETWORKAREA は,::GetMonitorInfo で戻されるものと同じ?
システム 0 61 1920 1080
アプリケーション 0 122 3840 2160
::GetSystemMetrics(SM_?VIRTUALSCREEN) は,-1920 0 .
::GetSystemMetrics(SM_C?VIRTUALSCREEN) は,上をずらしているので少し異なる.
システム 3840 1210
アプリケーション 5760 2160
https://learn.microsoft.com/ja-jp/windows/win32/gdi/the-virtual-screen
tcsncpy_s Buffer is too small
先日更新した ツール をテストしていると,フォントによりアプリケーションエラー?となってしまう.
デバッガで追いかけると,
—————————
Microsoft Visual C++ Runtime Library
—————————
Debug Assertion Failed!
Program: c:\Temp\i_Tools\TToPA\Debug.120\TToPA.exe
File: f:\dd\vctools\crt\crtw32\h\tcsncpy_s.inl
Line: 62
Expression: (L"Buffer is too small" && 0)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
—————————
中止(A) 再試行(R) 無視(I)
—————————
CRichEditCtrl を使用した CHARFORMATW の szFaceName の指定がうまくなかった.
::TcsNCpy(cf.szFaceName,LF_FACESIZE-1,faceName,LF_FACESIZE-1) ;
::TcsNCpy は,幾つかの環境でビルドできる様にしたもので,今回の場合は ::tcsncpy_s と同様もの.
faceName に与えたものが L"Bahnschrift Light SemiCondensed" で,コピー先のバッファが足りないため.
正しくは,
::TcsNCpy(cf.szFaceName,LF_FACESIZE-0,faceName,LF_FACESIZE-1) ;
これらの動作は,LOGFONT の時にもよく利用する.
既存のコードを検索してみると,LF_FACESIZE を正しく指定できていた.
::TcsCpy(lf.lfFaceName,LF_FACESIZE,tstring(faceName).substr(0,LF_FACESIZE-1).c_str()) ;
与えるデータは LF_FACESIZE-1 としている.