ホーム » VC (ページ 3)
「VC」カテゴリーアーカイブ
GetGlyphOutline ::PolyPolygon
求めたアウトラインをウィンドウに表示できる様な変換のコードを書いたので,その動作のテスト.
{
HWND hWnd = ::GetConsoleHwnd() ;
RECT rect = ::GetClientRect(hWnd) ;
POINT point= ::RECT_center(rect) ;
int ch = ::RECT_width(rect)/str.length()*10/7 ;
{
HDC hDC = ::GetDC(hWnd) ;
{
#define face_A _T("Arial")
#define face_U _T("Meiryo UI")
#define face_W _T("Wingdings")
{
::ClearWindow(hWnd) ;
int ry = -30 ;
tstring face_name = face_U ;
vv_PLF vv_plf= ::GetTTOutline(hDC,point,false,str.c_str(),face_name.c_str(),ch,0,0,ry,FW_DONTCARE) ;
v_Vd2A v_v2a = ::ToVd2A(vv_plf) ;
::PolyPolygon(hDC,v_v2a) ;
}
}
::ReleaseDC(hWnd,hDC) ;
}
}
::GetTTOutline の中では,文字の傾き,文字列の回転,Y の反転,表示位置の移動を行っている.
更に三角形に分割.
vv_PLF vv_plf= ::GetTTOutline(hDC,point,false,str.c_str(),face_name.c_str(),ch,0,0,ry,FW_DONTCARE) ;
// v_Vd2A v_v2a = ::ToVd2A(vv_plf) ;
v_Vd2A v_v2a = ::PLF_triangulation(vv_plf) ;
error C2061 , C2091 , C2809 , C2556
1997/06 に作成したプロジェクトをビルドすると…
--------------------Configuration: FontFam - Win32 Release--------------------
FontFam.exe - 0 error(s), 0 warning(s)
--------------------Configuration: FontFam - Win32 Debug--------------------
Compiling...
FontFDlg.cpp
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2061: syntax error : identifier 'THIS_FILE'
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2091: function returns function
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2809: 'operator new' has no formal parameters
c:\program files (x86)\microsoft visual studio\vc98\include\new(36) : error C2061: syntax error : identifier 'THIS_FILE'
c:\program files (x86)\microsoft visual studio\vc98\include\new(37) : error C2091: function returns function
c:\program files (x86)\microsoft visual studio\vc98\include\new(37) : error C2556: 'void *(__cdecl *__cdecl operator new(void))(unsigned int,const struct std::nothrow_t &)' : overloaded function differs only by return type from 'void *(__cdecl *__cd
ecl operator new(void))(unsigned int)'
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : see declaration of 'new'
c:\program files (x86)\microsoft visual studio\vc98\include\new(41) : error C2061: syntax error : identifier 'THIS_FILE'
c:\program files (x86)\microsoft visual studio\vc98\include\new(42) : error C2091: function returns function
c:\program files (x86)\microsoft visual studio\vc98\include\new(42) : error C2556: 'void *(__cdecl *__cdecl operator new(void))(unsigned int,void *)' : overloaded function differs only by return type from 'void *(__cdecl *__cdecl operator new(void))
(unsigned int)'
c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : see declaration of 'new'
c:\program files (x86)\microsoft visual studio\vc98\include\new(42) : error C2809: 'operator new' has no formal parameters
c:\program files (x86)\microsoft visual studio\vc98\include\new(42) : error C2065: '_P' : undeclared identifier
Error executing cl.exe.
FontFam.exe - 11 error(s), 0 warning(s)
以前は <memory> の インクルードを追加 することで対応していた.
原因は,幾つかのインクルードが次のコードより後に存在しているため?
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
コンソール AP で DC の使用
ChatGPT で「Windows コンソールアプリで DC を使用する方法」と入力してみた.
すると,使えそうなコードが表示された.
#include <Windows.h>
#include "i_define.hxx"
#include "con_wnd.hxx"
int main() {
// 1. コンソールウィンドウのハンドルを取得する
HWND consoleWindow = ::GetConsoleWindow();
// 2. コンソールウィンドウのDCを取得する
HDC consoleDC = GetDC(consoleWindow);
// 3. DCを使用して描画する
TextOut(consoleDC, 10, 100, _T("Hello, World!"), _tcslen(_T("Hello, World!")));
// 4. DCを解放する
ReleaseDC(consoleWindow, consoleDC);
return 0;
}
そのままではエラーになる部分があったので,少し修正している.
コンソール AP のウィンドウで GDI が使えるのは知らなかった.
BMP を表示するコード.
{
// ...
tstring dib_name = file_name ;
if (::File_IsNothing(dib_name)) { return false ; }
i_DIB dib = ::DIB_Load(dib_name.c_str()) ;
{
HWND hWnd = ::GetConsoleWindow() ;
{
RECT rect = { 0 } ;
::GetWindowRect(hWnd,&rect) ;
HDC hDC = ::GetDC(hWnd) ;
::DrawDIB(hDC,rect,dib) ;
::ReleaseDC(hWnd,hDC) ;
}
}
// ...
}
{
HWND hWnd = ::GetConsoleHwnd () ;
D_I_E die ;
die.SetDocPath(dib_name.c_str()) ;
die.Draw(hWnd) ;
}
error C2678: 二項演算子 ‘=’ :
ある処理を関数にしてコンパイルすると,
--------------------構成: VFDiv_1 - Win32 Debug--------------------
コンパイル中...
VFDiv_1V.cpp
c:\program files (x86)\microsoft visual studio\vc98\include\algorithm(232) : error C2678: 二項演算子 '=' : 型 'const struct Vector2<double>' の左オペランドを扱う演算子は定義されていません。(または変換できません)(新しい動作; ヘルプを参照)
c:\program files (x86)\microsoft visual studio\vc98\include\algorithm(228) : コンパイルされたクラスのテンプレートのインスタンス化 'void __cdecl std::_Iter_swap(const struct Vector2<double> *,const struct Vector2<double> *,struct Vector2<double> *)' の参照を確認してください
c:\program files (x86)\microsoft visual studio\vc98\include\algorithm(232) : error C2678: 二項演算子 '=' : 型 'const struct Vector2<double>' の左オペランドを扱う演算子は定義されていません。(または変換できません)(新しい動作; ヘルプを参照)
c:\program files (x86)\microsoft visual studio\vc98\include\algorithm(228) : コンパイルされたクラスのテンプレートのインスタンス化 'void __cdecl std::_Iter_swap(const struct Vector2<double> *,const struct Vector2<double> *,struct Vector2<double> *)' の参照を確認してください
cl.exe の実行エラー
VFDiv_1.exe - エラー 2、警告 0
対象が ‘const struct Vector2<double>’ となっているので,わかり辛かった.
次の関数の,’const Vd2A& v2a’ を std::reverse(v2a.begin(),v2a.end()) として使用しているのが原因.
PLF_face_l PLF_triangulation (const Vd2A& v2a)
{
// ...
std::reverse(v2a.begin(),v2a.end()) ;
// ...
}
VirusTotal Cylance Unsafe
1 年位前から,exe をビルドしてデバッグが終わると VirusTotal でチェックしている.
それで,誤検知されやすいと思われる VC のバージョンなどのメモ.
VC6.exe では,ほとんどが何らかのものに引っ掛かってしまう.
SecureAge Malicious
VC8.exe や VC9.exe も何かに引っ掛かってしまうことが多い.
VC 10 ~ VC 12 では,あまり規則性はわからない.コードによる?
VC 14 以降は,普通の MFC のコードであればほぼ問題なさそう.
但し最初のうちは,ほとんど Cylance Unsafe となってしまう.
が,数日経過すると警告は消えることが多い.
error C2668: ‘abs’
1>------ ビルド開始: プロジェクト: ClCpy, 構成: Debug Win32 ------
1>コンパイルしています...
1>ClCpyDlg.cpp
1>l:\document\develop\tools\_free\tiny\clcpy\clcpydlg.cpp(396) : error C2668: 'abs' : オーバーロード関数の呼び出しを解決することができません。(新機能 ; ヘルプを参照)
1> c:\program files (x86)\microsoft visual studio 8\vc\include\math.h(539): 'long double abs(long double)' の可能性があります。
1> c:\program files (x86)\microsoft visual studio 8\vc\include\math.h(491): または 'float abs(float)'
1> c:\program files (x86)\microsoft visual studio 8\vc\include\math.h(487): または 'double abs(double)'
1> c:\program files (x86)\microsoft visual studio 8\vc\include\math.h(485): または 'long abs(long)'
1> c:\program files (x86)\microsoft visual studio 8\vc\include\stdlib.h(415): または 'int abs(int)'
1> 引数リスト '(size_t)' を一致させようとしているとき
1>ビルド時間 0:07
1>ClCpy - エラー 1、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
次の様に long にキャストすることで対応.
size_t len_ = ::abs(long(lenS-lenD)) ;
Win11 MFC80u.dll などの場所
VC 2005 で作成した exe がうまく起動しないと連絡が入った.
すぐに dll などがないためとわかり,VC 2005 SP1 vcredist_x86.exe を入れて対応してもらった.
https://jml.mish.work/index.php/cpp/ref-vcredist-xxx-exe.html
それで,Win11 環境の c:\Windows\WinSxS\ の MFC80*.dll を見ると,それらしいものが見当たらない.
Win10 では …\WinSxS\ に存在する.
explorer で検索すると Win11 では ..\WinSxS\Fusion\ 以下になっている.
.NET ZipFile C++/CLI
ZipFile クラスのサンプル を VC 2012 C++/CLI で.
Win32 コンソール AP としてプロジェクトを作成.
CPP を次の様に変更.
#include <stdio.h>
#include <tchar.h>
// using System;
// using System.IO.Compression;
#using <System.dll>
#using <System.IO.Compression.FileSystem.dll>
// class Program
// {
// static void Main(string[] args)
// {
int _tmain(int argc, _TCHAR* argv[])
{
// string startPath = @"./start";
// string zipPath = @"./result.zip";
// string extractPath = @"./extract";
System::String^ startPath = _T("./start") ;
System::String^ zipPath = _T("./result.zip") ;
System::String^ extractPath = _T("./extract") ;
// ZipFile. CreateFromDirectory(startPath, zipPath);
System::IO::Compression::ZipFile::CreateFromDirectory(startPath, zipPath);
// ZipFile. ExtractToDirectory(zipPath, extractPath);
System::IO::Compression::ZipFile::ExtractToDirectory(zipPath, extractPath);
return 0;
}
// }
// }
そのままビルドすると…
1>------ ビルド開始: プロジェクト: T_ZIP_C, 構成: Debug Win32 ------
1> T_ZIP_C.cpp
1>d:\document\vs\vs\2012\t_clr\t_zip_c\t_zip_c.cpp(6): fatal error C1190: マネージ ターゲット コードには '/clr' が必要です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
1>------ ビルド開始: プロジェクト: T_ZIP_C, 構成: Debug Win32 ------
1> T_ZIP_C.cpp
1>T_ZIP_C.cpp(7): fatal error C1107: アセンブリ 'System.IO.Compression.FileSystem.dll' がみつかりませんでした: /AI または LIBPATH 環境変数を使用してアセンブリ検索パスを指定してください。
========== ビルド: 0 正常終了、1 失敗、3 更新不要、0 スキップ ==========
「追加の #using ディレクトリ」に dll の場所を指定して通る様にはなったが,これで良いかがわからない.
ほとんど何も入っていない環境で実行すると,
---------------------------
T_ZIP_C.exe - システム エラー
---------------------------
MSVCR110.dll が見つからないため、コードの実行を続行できません。プログラムを再インストールすると、この問題が解決する可能性があります。
---------------------------
OK
---------------------------
VC 2013 や 2015 でビルドしたものも試してみたが,この環境では実行できなかった.
対応するものを入れる必要があるのか?
https://jml.mish.work/index.php/cpp/ref-vcredist-xxx-exe.html
2024/07/05
VC のバージョン(実際は .NET のバージョン?)により,微妙に zip の内容が異なるみたい.
3MF データが開けない?
簡易 Web サーバ C++/CLI
先日の C# のコードから C++/CLI に書き直したものの 更新版 .
index.html の作成と,ContentType の設定,日本語ファイル名への対応など.
#ifdef __cplusplus_cli
#using <System.dll>
#using <System.Web.dll>
#include <vcclr.h>
#endif
///////////////////////////////////////////////////////////////////////////
#include "S_Exec.hxx"
#include "str_CLI.hxx"
#include "filestat.hxx"
#include "filepath.hxx"
#include "ask_path.hxx"
#include "itls_tmp.hxx"
#include "textfile.hxx"
#include "htmout.hxx"
#include "stringfn.hxx"
///////////////////////////////////////////////////////////////////////////
struct MIME_type {
LPCTSTR FExt ;
LPCTSTR Type ;
} ;
// https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
const MIME_type MIME_type_tbl[] =
{
_T("htm" ) , _T("text/html") ,
_T("html") , _T("text/html") ,
_T("txt" ) , _T("text/plain") ,
_T("bmp" ) , _T("image/bmp") ,
_T("jpeg") , _T("image/jpeg") ,
_T("jpg" ) , _T("image/jpeg") ,
_T("png" ) , _T("image/png") ,
_T("svg" ) , _T("image/svg+xml") ,
_T("bin" ) , _T("application/octet-stream") ,
_T("pdf" ) , _T("application/pdf") ,
_T("zip" ) , _T("application/zip") ,
_T(" " ) , _T("") ,
_T("\0" ) , _T("") ,
_T("" ) , _T("") ,
} ;
inline tstring get_MIME_type (LPCTSTR ext_)
{
tstring type = _T("application/octet-stream") ;
tstring ext = ::String_ToLower(ext_) ;
if (ext.empty()) {
return type ;
}
const MIME_type* mm_ty = MIME_type_tbl ;
{
for (size_t index=0 ; index<countof(MIME_type_tbl) ; index++)
{
tstring fext = mm_ty[index].FExt ;
tstring ftyp = mm_ty[index].Type ;
if (fext.length() == 0) { continue ; }
if (fext.length() != ext.length()) { continue ; }
if (ext == fext) {
return mm_ty[index].Type ;
}
}
}
return type ;
}
///////////////////////////////////////////////////////////////////////////
inline tstring HT_Make_index_content (c_tstring& fold)
{
v_tstring sub_folds = ::EnumFolders(fold.c_str()) ;
v_tstring htm_files = ::EnumFiles (fold.c_str(),_T("*.htm*")) ;
tstring foldName = ::Path_GetTitle(fold) ;
tstring htm_str ;
{
Xml_E htm = HtmOut::html() ;
{
Xml_E head(HTM_head) ;
{
head.AddChild(HtmOut::charset_UTF_8()) ;
head.AddChild(HtmOut::meta_viewport()) ;
head.AddChild(HtmOut::title(foldName)) ;
}
{
head.AddChild(HtmOut::comment()) ;
}
htm.AddChild(head) ;
}
{
Xml_E body(HTM_body) ;
{
{
body.AddChild(HtmOut::a_parent()) ;
body.AddChild(HtmOut::hr()) ;
}
{
for (size_t index=0 ; index<sub_folds.size() ; index++) {
tstring fold = sub_folds[index] ;
fold = ::Path_DelLastSP(fold) ;
Xml_E a_fold = HtmOut::a(::Path_GetName(fold)+_T("/")) ;
body.AddChild(a_fold) ;
body.AddChild(HtmOut::br()) ;
}
body.AddChild(HtmOut::hr()) ;
}
{
for (size_t index=0 ; index<htm_files.size() ; index++) {
tstring html = htm_files[index] ;
Xml_E a_html = HtmOut::a(::Path_GetName(html)) ;
body.AddChild(a_html) ;
body.AddChild(HtmOut::br()) ;
}
}
}
htm.AddChild(body) ;
}
htm_str = htm.ToText() ;
}
return htm_str ;
}
tstring Make_index (c_tstring& fold)
{
tstring result = ::HT_Make_index_content(fold) ;
return result ;
}
///////////////////////////////////////////////////////////////////////////
bool web_server (c_tstring& fold,const u_16 port)
{
tstring root_ = fold ;
tstring port_ = ::To_tstring(port) ;
tstring pref_ = _T("http://127.0.0.1:")+port_+_T("/") ;
System::String^ root = ::to_gcString(root_) ;
System::String^ prefix = ::to_gcString(pref_) ;
System::Console::WriteLine(prefix) ;
System::Net::HttpListener^ listener = gcnew System::Net::HttpListener();
listener->Prefixes->Add(prefix);
listener->Start();
while (true) {
System::Net::HttpListenerContext^ context = listener->GetContext();
System::Net::HttpListenerRequest^ req = context->Request;
System::Net::HttpListenerResponse^ res = context->Response;
System::String^ path = root + req->RawUrl->Replace("/", "\\");
path = System::Web::HttpUtility::UrlDecode(path) ;
{
System::Console::WriteLine(req->RawUrl);
System::Console::WriteLine(path) ;
}
if (System::IO::File::Exists(path)) {
}
if (System::IO::File::Exists(path)) {
tstring ext = ::Path_GetExtLow(::to_tstring(path)) ;
array<System::Byte>^ content = System::IO::File::ReadAllBytes(path);
res->ContentType = ::to_gcString(::get_MIME_type(ext.c_str())) ;
res->OutputStream->Write(content, 0, content->Length);
}
else {
tstring cnt_index = ::Make_index (::to_tstring(path)) ;
array<System::Byte>^ content ;
{
static long i_count = 0 ;
i_count++ ;
tstring tmp_path = ::Get_i_Tools_tmp_date() ;
tstring htm_name = ::To_tstring(port) + _T("_") + ::u32to0t(i_count,10,4) + _T(".htm") ;
tstring out_path = ::Path_AddLastSP(tmp_path) + htm_name ;
::SaveUTF8(out_path.c_str(),cnt_index) ;
content = System::IO::File::ReadAllBytes(::to_gcString(out_path.c_str())) ;
}
res->ContentType = ::to_gcString(::get_MIME_type(_T("htm"))) ;
res->OutputStream->Write(content, 0, content->Length);
}
res->Close();
}
return true ;
}
///////////////////////////////////////////////////////////////////////////
bool test (c_tstring& str)
{
tstring fold = str ;
{
if (::File_IsDirectory(fold)) { ; }
else { fold = ::Path_GetDir(fold) ; }
}
std::terr << fold << std::endl ;
{
u_16 tick = u_16(::GetTickCount()) ;
u_16 port = u_16(50000 + (tick&0x1fff)) ;
{
tstring port_ = ::To_tstring(port) ;
tstring pref_ = _T("http://127.0.0.1:")+port_+_T("/") ;
S_Exec se ;
se.SetFile(pref_.c_str()) ;
se.Execute() ;
}
::web_server(fold,port) ;
}
return true ;
}
///////////////////////////////////////////////////////////////////////////
int _tmain (int argc,_TCHAR* argv[])
{
tstring path ;
{
#ifdef OFN_filter_All
path = ::ask_path(false) ;
// path = ::ask_path(true) ;
#else
path = ::ask_cli(_T("folder ... ? =")) ;
#endif
}
if (!path.empty()) {
::test(path) ;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
#include "messbar.cxx"
* 幾つかのコードが揃っていないため,そのままではビルドできません.
https://jml.mish.work/index.php/i-tools/web-svr.html
2024/11/02
VC 2005 でビルド可能な一式を用意しました.
https://itl.mish.work/i_Tools/Doc/blog/vc/T_h_lstn.zip
C# のコードを C++/CLI に
先日の「簡易 Web サーバ C#」のコードを C++ で.
///////////////////////////////////////////////////////////////////////////////////
// C# -> C++/CLI
///////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <tchar.h>
//using System;
//using System.IO;
//using System.Net;
#using <System.dll>
bool test (void)
{
//
// class SimpleWebServer
// {
// static void Main()
// {
// string root = @"c:\wwwroot\"; // ドキュメント・ルート
// root = @".\";
System::String^ root = "./" ;
// string prefix = "http://*/"; // 受け付けるURL
// prefix = "http://127.0.0.1:65432/" ;
System::String^ prefix = "http://127.0.0.1:55555/" ;
//
// HttpListener listener = new HttpListener();
System::Net::HttpListener^ listener = gcnew System::Net::HttpListener();
// listener. Prefixes. Add(prefix); // プレフィックスの登録
listener->Prefixes->Add(prefix);
// listener. Start();
listener->Start();
//
// while (true) {
while (true) {
// HttpListenerContext context = listener. GetContext();
System::Net::HttpListenerContext^ context = listener->GetContext();
// HttpListenerRequest req = context. Request;
System::Net::HttpListenerRequest^ req = context->Request;
// HttpListenerResponse res = context. Response;
System::Net::HttpListenerResponse^ res = context->Response;
//
// Console. WriteLine(req. RawUrl);
System::Console::WriteLine(req->RawUrl);
//
// // リクエストされたURLからファイルのパスを求める
// string path = root + req. RawUrl. Replace("/", "\\");
System::String^ path = root + req->RawUrl->Replace("/", "\\");
//
// // ファイルが存在すればレスポンス・ストリームに書き出す
// if ( File. Exists(path)) {
if (System::IO::File::Exists(path)) {
// byte[] content = File. ReadAllBytes(path);
array<System::Byte>^ content = System::IO::File::ReadAllBytes(path);
// res. OutputStream. Write(content, 0, content. Length);
res->OutputStream->Write(content, 0, content->Length);
// }
}
// res. Close();
res->Close();
// }
}
// }
// }
//
return true ;
}
int _tmain(int argc, _TCHAR* argv[])
{
::test() ;
return 0;
}
VC 8 で C++/CLI
VC 10 ではある程度確認が取れたので,今度は VC 8 で.
先ず,コンソール AP .ビルドすると,
1>------ ビルド開始: プロジェクト: T_Con_1, 構成: Debug Win32 ------
1>コンパイルしています...
1>T_Con_1.cpp
1>EnumFile.hxx MessageBar No Support
1>C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include\vcclr.h(43) : error C2446: '!=' : 'int' 型から 'cli::interior_ptr<Type>' 型への変換ができません。
1> with
1> [
1> Type=unsigned char
1> ]
1>T:\Develop\_.SRC\_CLI\str_CLI.hxx(41) : error C2446: '==' : 'int' 型から 'System::String ^' 型への変換ができません。
1> 使用可能なユーザー定義された変換演算子がない、または
1> 演算型のボックス化された形式からターゲット型への標準変換は存在しません
1>T:\Develop\_.SRC\_CLI\str_CLI.hxx(61) : warning C4267: '初期化中' : 'size_t' から 'int' に変換しました。データが失われているかもしれません。
1>T:\Develop\_.SRC\_CLI\str_CLI.hxx(64) : warning C4267: '初期化中' : 'size_t' から 'int' に変換しました。データが失われているかもしれません。
1>T_Con_1 - エラー 2、警告 2
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
vcclr.h 内のエラーは,次の様に cpp の最初で vcclr.h を読み込むことで回避できる.
#ifdef __cplusplus_cli
#include <vcclr.h>
#endif
もう一つのエラーは次の所で,str が nullptr でないかを比較している所.
tstring to_tstring (System::String^ str)
{
if (str == nullptr) { return _T("") ; }
pin_ptr <const wchar_t> pStr = PtrToStringChars(str) ;
tstring tstr = pStr ;
return tstr ;
}
fatal error C1010
昨日から VC6 で開いたままだったプロジェクトをビルドすると,あまり見慣れないエラーが…
--------------------Configuration: AsTrmM - Win32 Debug--------------------
Compiling...
HProRNew.cpp
t:\develop\_.src\...\hprornew.cpp(113) : fatal error C1010: unexpected end of file while looking for precompiled header directive
Error executing cl.exe.
AsTrmM.exe - 1 error(s), 0 warning(s)
他の環境で試そうとプロジェクトを閉じようとすると,保存するかの問合せが入った.
保存された dsp と先日バックアップしたそれと比べると,不要な cpp が追加されていた.
ソースを開いた時,操作ミスで間違ってビルド対象に cpp が追加されてしまったみたい.
不要な cpp をプロジェクトから外して対応.うまくいった.
私の場合,自動生成される以外のソースは,次の様な複数の cpp をプロジェクトに追加して運用しています.
ComUse01.cpp
#include "StdAfx.h"
#include "ComPrj00.hpp"
#include "Point.cxx"
#include "Matrix.cxx"
// ...
ComPrj00.hpp
#include "i3DV.h" // App.h
#include "ColorHSV.hxx"
// ...
高 DPI ペンの幅
引き続きやっているが,なかなか難しい.
左は「非対応.exe」を「プロパティ」で「アプリケーション」にしたもの.
0.2 mm の指定で印刷する場合は問題ないが,27 インチ 4K では 1 ピクセルになり非常に見辛い.
今度は,VC 12 以降で「モニターごとの高い DPI 認識」としたもの.
Win7 では「非対応.exe」でも「アプリケーション」と指定したものの様な動作?
8.1 以降は,「DPI 認識」で指定したものが効いている?
4K 環境の Win10 で「非対応.exe」.
exe のプロパティで「システム(拡張)」としたもの.
0.3 mm の線を表示すると「システム(拡張)」としたものの方がきれい.
AP の作り方にもよると思うが,exe のプロパティで「システム(拡張)」としたものが一番良さそう.
「アプリケーション」にしてしまうと?,他のモニタに移動した時に大きさなどがうまくない.
::GetDpiForWindow
高 DPI 関連でいろいろと調べてみると ::GetDpiForWindow を使う必要がありそう.
ただ使えるのが Win10 1607 以降みたいで,その辺りをどうしたものか?
次の様に呼出せば 指定した hwnd の値が取れることは確認 .
#if (_MSC_VER >= 1900)
{
UINT dpi = ::GetDpiForWindow(hwnd) ;
std::terr << dpi << std::endl ;
}
#endif
ただ,旧 Windows では存在しないため実行時エラーになる.
そのため ::GetProcAddress を 利用した方法に .
// UINT GetDpiForWindow ( [in] HWND hwnd ) ;
typedef UINT (WINAPI* P_GDFW)(HWND) ;
UINT GetDPI (HWND hwnd)
{
UINT dpi = 96/2 ;
HMODULE user32 = ::GetModuleHandle(TEXT("user32.dll")) ;
P_GDFW p_GetDpiForWindow = (P_GDFW)::GetProcAddress(user32,"GetDpiForWindow") ;
if (p_GetDpiForWindow != NULL) {
dpi = p_GetDpiForWindow(hwnd) ;
}
else {
HDC hdc = ::GetDC(hwnd) ;
dpi = ::GetDeviceCaps(hdc,LOGPIXELSX) ;
::ReleaseDC(hwnd,hdc) ;
}
return dpi ;
}
解像度と DPI の関係が,まだうまく理解できていない.
::GetDpiForWindow は,指定した hwnd の DPI が取得できている.
::GetDeviceCaps では,プライマリの情報が取れる.
「非対応」の場合はスケーリングされた値,「モニターごと」の場合は 100% での値?
buf = string ( buf.c_str () )
先日の共通のコードでのバグ.
tstring ask_cli (LPCTSTR msg=_T(""))
{
tstring cli ;
while(true) {
tstring buf ;
buf.resize(1000) ;
std::terr << msg ;
std::tin.getline(&buf[0],std::streamsize(buf.size())) ;
// buf = ::QuotM_Del_All(buf.c_str()) ;
if (buf == _T("q")) { break ; }
else if (buf == _T("Q")) { break ; }
if (buf.empty()) { continue ; }
cli = buf.c_str() ;
break ;
}
return cli ;
}
ループを抜けるために “q” や “Q” と比較している部分が機能しない(break しない).
原因は “q\0\0\0…” と “q\0” を比べているため.
そのため,比較する前に次の様にするとうまく機能する.
{
tstring tmp = buf.c_str() ;
buf = tmp ;
}
MFC であれば CString::ReleaseBuffer(-1) が使えるが…
buf = tstring(buf.c_str()) とすることで対応.
::GetDeviceCaps(dc,HORZRES)
先日のコード を利用して,Windows API の動作のテスト.
#include <clocale>
#include <iostream>
#include "_tdefine.hxx"
#include "cmd_line.hxx"
#include "ask_cli.hxx"
//#include "ask_path.hxx"
#include <Windows.h>
bool test (c_tstring& str)
{
// std::terr << str << std::endl ;
HDC dc = ::GetDC(NULL) ;
if (dc != NULL) {
int hres = ::GetDeviceCaps(dc,HORZRES) ;
int vres = ::GetDeviceCaps(dc,VERTRES) ;
std::terr
<< _T("HORZRES=") << hres << _T("\t")
<< _T("VERTRES=") << vres << _T("\t")
<< std::endl ;
}
return true ;
}
int _tmain (int argc,TCHAR* argv[])
{
_tsetlocale(LC_ALL,_T("")) ;
{
::reg_argv (argc,argv) ;
}
{
// ::call_func(argc,argv) ;
}
{
::test(_T("Test")) ;
}
::ask_wait() ;
return 0 ;
}
::GetDpiForWindow を追加して FHD と 4K 環境で実行.
bool test (c_tstring& str)
{
HWND hwnd = ::GetConsoleHwnd() ;
{
HDC dc = ::GetDC(hwnd) ;
if (dc != NULL) {
int hres = ::GetDeviceCaps(dc,HORZRES) ;
int vres = ::GetDeviceCaps(dc,VERTRES) ;
std::terr
<< _T("HORZRES=") << hres << _T("\t")
<< _T("VERTRES=") << vres << _T("\t")
<< std::endl ;
}
}
// #ifdef DPI_AWARENESS_UNAWARE
{
HWND hwnd = ::GetConsoleHwnd() ;
UINT dpi = ::GetDpiForWindow(hwnd) ;
std::terr << dpi << std::endl ;
}
// #endif
return true ;
}
コンソール AP のための最初のコード
API などをテストするために,個人的に使用している C++ のコード.
#include <clocale>
#include <iostream>
#include "_tdefine.hxx"
#include "cmd_line.hxx"
#include "ask_cli.hxx"
//#include "ask_path.hxx"
bool test (c_tstring& str)
{
std::terr << str << std::endl ;
return true ;
}
inline bool call_func (int argc,TCHAR* argv[])
{
if (argc > 1) {
for (int index=1 ; index<argc ; index++) {
tstring av = argv[index] ;
::test(av) ;
}
}
else {
while(true) {
tstring path ;
{
#ifdef OFN_filter_All
path = ::ask_path(false) ;
#else
path = ::ask_cli(_T("file ... ? =")) ;
#endif
}
if (path.empty()) { break ; }
::test(path) ;
}
}
return true ;
}
int _tmain (int argc,TCHAR* argv[])
{
_tsetlocale(LC_ALL,_T("")) ;
{
::reg_argv (argc,argv) ;
}
{
::call_func(argc,argv) ;
}
{
::test(_T("Test")) ;
}
::ask_wait() ;
return 0 ;
}
//#include "messbar.cxx"
インクルードしているファイルは cpp6_hxx.zip にある.
上のコードを test.cpp などとして保存し,同じ所に zip を展開.
g++ test.cpp などでコンパイル可能.
これらを使用したコード.
https://dev.mish.work/wordpress/?s=reg_argv
Win11 22H2
昨日 Win11 環境に VS 2005 から 2022 をインストール .
その後,幾つかのコードをビルドして動作を確認.
仮想環境の Win11 22H2 で,KB5019509 の更新があった.
幾つか試したいことができたので,ホストの Win11 も 22H2 にしたくなった.
次の所から入って 22H2 をインストール.
https://www.microsoft.com/ja-jp/software-download/windows11/
1 時間程度かかった.
先日インストールした VC 6 を起動してみると…
うまく起動する.ビルドも問題なさそう.仮想マシンで動作していたのは 22H2 だったからか?
ステップ実行できない現象はあるが,何とか使える.
2022/10/23
ステップ実行した場合のメッセージが,仮想マシンと異なる.
仮想マシンは
—————————
Microsoft Visual C++
—————————
ハンドルされていない例外 は i3DV.exe (OLE32.DLL) にあります: 0xC0000005: Access Violation。
—————————
OK
—————————
ホストは
—————————
Microsoft Visual C++
—————————
OLE リモート呼び出しデバッグには管理者権限が必要です: この機能は使用できません。.
—————————
OK
—————————
「Win10 VC6 OLE」で検索すると,次の所が見つかった.
Windows10でVC6を使いたい
どうも「ツール」-「オプション」-「デバッグ」の「OLE RPC デバッグ」のチェックを外す必要があるらしい.
チェックを外す操作は,一度「ジャスト イン タイム デバッグ」にチェックを入れてから操作する必要がある.
RC4005: ‘IDR_MANIFEST’ : redefinition
VC6 から順に更新してきたプロジェクトをビルドしていると,warning RC4005: ‘IDR_MANIFEST’ : redefinition .
...
6>------ ビルド開始: プロジェクト:ClipView, 構成:Debug Win32 ------
6>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include\afxres.h(32): warning RC4005: 'IDR_MANIFEST' : redefinition
6>
6> Clip140.vcxproj -> c:\Temp\MICSTool\ClipView\Debug.140\ClipView.exe
6> Clip140.vcxproj -> c:\Temp\MICSTool\ClipView\Debug.140\ClipView.pdb (Full PDB)
========== ビルド: 6 正常終了、0 失敗、16 更新不要、0 スキップ ==========
resource.h を見ると,確かに IDR_MANIFEST が定義されている.
どのタイミングで追加したのかは覚えてないが,resource.h での定義は不要と思われるので削除.
Win11 に VS 6 のインストール
先日,Win11 環境に VS6 をインストールした.
手順は Win10 の時と同様 で,DB 関係が入らない様に.
VB6 は起動した.
が,VC6 は起動できない.
昨日,Win10 上の仮想マシンの Win11 に VS6 と SP6 をインストール.
この時 VC 6 は起動可能で,ビルド,デバッグなども動作した.
今日,それを確認すると,デバッグができなくなっている.
全くできないわけではないが,ブレークするとその後がうまくない.
何かが更新されて動作しなくなったのか?
Win11 上の仮想マシンとしての Win11 も,起動はできるがデバッグがうまくない.
Win10 の時もそうだったが,何かとの相性? … Win11 21H2 だったため.
2022/10/18
以前使っていた WinXP の VHD があったので,それを Win11 上の仮想マシンとして追加.
最近使ってなかったので,いろいろと問題が…
SMB1 や mklink .
なかなかいい運用が見つからない.
2022/10/23
22H2 に上げて うまく動作する様になった.
2023/10/30
VC 6 は,Win 10 ,11 で特に困ることはなく利用できている.
たまに使用する機能でうまくないのは「コンポーネントギャラリ」くらい?
Win11 はシステムドライブが SSD のため,$(OutDir) は「シンボリック リンク」にしている.