ホーム » MFC (ページ 4)
「MFC」カテゴリーアーカイブ
MBCS_Support_Deprecated_In_MFC
最初 VC 6 で作成したプロジェクト.VC 8 までは順にあげてあった.これをさらに VC 14.x まであげたもの.
その中の一部のプロジェクトを「マルチ バイト文字セットを使用する」に変更してビルドすると,
1>------ ビルド開始: プロジェクト:TEDHPro4, 構成:Debug Win32 ------ 1> StdAfx.cpp 1>c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\afx.h(38): warning C4996: 'MBCS_Support_Deprecated_In_MFC': MBCS support in MFC is deprecated and may be removed in a future version of MFC. 1> c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\afx.h(33): note: 'MBCS_Support_Deprecated_In_MFC' の宣言を確認してください 1> _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h) 1> TEDHPro4.cpp 1> TEDHProD.cpp 1> コードを生成中... 1>StdAfx.obj : warning LNK4075: /EDITANDCONTINUE は /OPT:LBR の指定によって無視されます。 1> TEDH4140.vcxproj -> c:\Temp\EDHProM\TEDHPro4\Debug.140\TEDHPro4.exe 1> TEDH4140.vcxproj -> c:\Temp\EDHProM\TEDHPro4\Debug.140\TEDHPro4.pdb (Full PDB) ========== ビルド: 1 正常終了、0 失敗、4 更新不要、0 スキップ ==========
今回のプロジェクトは,dll の単体テストのためのものなのでこのまま(warning が出る状態)とする.
これを回避するには「文字セット」を「Unicode 文字セットを使用する」にすること.
どうしても warning C4996 を消したいのではあれば,StdAfx.h で afx*.h のインクルードの前に NO_WARN_MBCS_MFC_DEPRECATION を定義すれば良い.
#define NO_WARN_MBCS_MFC_DEPRECATION
VC 14 デバッグ MFC にステップイン
VC 2015 で MFC を使用した SDI.exe をデバッグしていると,MFC のコードにステップインできない?
入っている他の VC で試すと VC 2013 まではうまく機能している.
検索しても,これはという内容には引っ掛からなかった?
アプリケーションクラスの CG3toMApp::InitInstance() を抜ける時,そのままステップ実行していると…
「Microsoft Symbol Servers」にチェックを付けて「読み込み」.
MFC ソース内のデバッグができる様になった.
設定としては「ツール」-「オプション」の中の「デバッグ」-「シンボル」.
2022/02
%TEMP% では消えてしまうので,シンボルキャッシュの場所を変更している.
VC フォールバック 設定
https://itl.mish.work/Iwao/Doc/other/vs/
https://jml.mish.work/index.php/cpp/vs-install.html
CMutex の使用でデッドロック?
何年も前(2015/11?)からなのかもしれないが,
今の PC になってから作成した exe が起動時やサムネイルの表示などで停止する現象が時々発生している.
発生する頻度が低いのと,現象が絞り切れていなかったのでそのままになっていた.
今日,デバッグしていると exe が起動しない.
その時までに起動済みのものは動作しているが,止まってしまうものもあり.
以前この現象が発生した時は再起動することで回避したが,今回はもう少し調べてみることにした.
デバッガで追いかけると CMutex の Lock(INFINITE) で戻って来ない.
使用している所は次の様な感じ.
{ _MutexS_ mt(FALSE,_T("DocIB::GetBitmap")) ; MutexS m(&mt) ; { // 共有のリソースに対する操作 } }
通常の動作では Unlock されないことがある様には思えないが…
デバッガを使っていて Lock 中に exe を強制終了してしまったか?
_MutexS_ UseGdiPlus::ME(FALSE,_T("UseGdiPlus::GP_Token")) ; { MutexS me(&ME) ; if (IsInitialized()) { // ... } // .. }
いい修正方法が思い浮かばないので,とりあえずメモ.
2021/02/19
その後いろいろと検索して調べたが,通常の動作ではロックされたままとなることはなさそう.
https://docs.microsoft.com/ja-jp/dotnet/standard/threading/mutexes
表示されてはないが起動したままの exe があるかと思い,タスクバーを見たが特になさそう.
昨日,わかっているものの幾つかは「タスクの終了」で終わらせている.
そうなるとロックされている Mutex は,自前のシェルエクステンションと思われる.
「タスクバー」に表示されている「エクスプローラ」は終了させたが,まだ誰かがロックしている.
画面には表示されていない explorer.exe が幾つかか存在したので,すべて終わらせた.
これでロックされた Mutex は解放されたみたい.
今度は,デバッガを使用してうまく起動しなかった exe をいろいろ試すことに.
デバッガで Lock した直後にブレイクポイントを設定して停止.
当然であるが他の exe を起動すると Lock の所で止まってしまう.
デバッガで Unlock の後まで実行すると,他の exe も止まっていた所から動き出す.
デバッガで Lock した直後に停止させて,他の exe を起動.
デバッガで「デバッガの停止」してみる(Unlock していない)と,他の exe が動き出す.
これらの動作を見ると,使い方としてはそれ程間違ってはなさそう.
コードを追いかける限りでは,「マズい」所がわからない.
複数のプロセスから呼ばれた時に意図しないタイミングとなってしまう所があるのか?
ある程度はっきりしたのは,自前のシェルエクステンションの GDIPlus 関係の時の Lock で止まっていること.
ドキュメント付きの起動で抜ける?
個人的なコートでのメモです.
普通に exe を起動してドキュメントを開くのは問題ない.
ドキュメント付きで起動すると,ウィンドウが表示されて,ドキュメントを読込み後終了してしまっている.
デバッガで追いかけると,ProcessShellCommand の呼び出しで FALSE となっている.
原因は,ドキュメントの読込み後にアプリケーションクラスにアクセスしている所で初期化が済んでないため.
初期化のコード(RcntFM)を CCommandLineInfo の前にして対応.
// メイン MDI フレーム ウィンドウを作成 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // ドラッグ/ドロップ オープンを許可します m_pMainWnd->DragAcceptFiles(); { RcntFM.Read() ; RcntFM.SetStartID(ID_RECENT_FILE_00) ; } // DDE、file open など標準のシェル コマンドのコマンドラインを解析します。 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew) { cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing ; } // コマンドラインでディスパッチ コマンドを指定します。 if (!ProcessShellCommand(cmdInfo)) return FALSE;
これをやっていて困ったのが,ソースのタイル表示.
VS 2019 ではうまく動作するが,2017 など他のものではエラーになってしまう.
--------------------------- GLSm140: devenv.exe - アプリケーション エラー --------------------------- 0x000000006359C044 の命令が 0x0000000000000000 のメモリを参照しました。メモリが read になることはできませんでした。 プログラムを終了するには [OK] をクリックしてください プログラムをデバッグするには [キャンセル] をクリックしてください --------------------------- OK キャンセル ---------------------------
MFC DLL error C2371 cerr
FBX SDK を使用したテストプロジェクト.
以前「MFC を使用する」になっていたもの.
関連するコードを変更して「MFC を使用しない」に書き換え.
そのままのコードを「MFC を使用する」に戻すと,…
--------------------構成: T_FBX - Win32 DebugM-------------------- コンパイル中... T_FBX.cpp c:\program files\microsoft visual studio\vc98\mfc\include\afx.h(1941) : error C2371: 'cerr' : 再定義されています。異なる基本型です。 c:\program files\microsoft visual studio\vc98\include\iostream(19) : 'cerr' の宣言を確認してください。 nothing FS_VER VC 6 200508 cl.exe の実行エラー T_FBX.exe - エラー 1、警告 0
前に変更しているが,元に戻す方が良いのか?
そもそもこの部分を削除した方が良いか?
https://dev.mish.work/wordpress/2020/04/17/rc1047-c2679/
今回は i_define.hxx から次の部分を削除.
#ifdef _MSC_VER #ifdef _MFC_VER #else #ifndef afxDump #define afxDump std::terr #endif #endif #endif
必要があれば i_debug.hxx に追加する.
CListBox などのオーナードロー
リストスクロール時,動作が逆に見える現象の調査のため調べたこと.
WinCore.cpp CWnd::OnMeasureItem での CtlType の値
/* * Owner draw control types */ #define ODT_MENU 1 #define ODT_LISTBOX 2 #define ODT_COMBOBOX 3 #define ODT_BUTTON 4 #if(WINVER >= 0x0400) #define ODT_STATIC 5 #endif /* WINVER >= 0x0400 */
/* * Listbox Styles */ #define LBS_NOTIFY 0x0001L #define LBS_SORT 0x0002L #define LBS_NOREDRAW 0x0004L #define LBS_MULTIPLESEL 0x0008L #define LBS_OWNERDRAWFIXED 0x0010L #define LBS_OWNERDRAWVARIABLE 0x0020L #define LBS_HASSTRINGS 0x0040L #define LBS_USETABSTOPS 0x0080L #define LBS_NOINTEGRALHEIGHT 0x0100L #define LBS_MULTICOLUMN 0x0200L #define LBS_WANTKEYBOARDINPUT 0x0400L #define LBS_EXTENDEDSEL 0x0800L #define LBS_DISABLENOSCROLL 0x1000L #define LBS_NODATA 0x2000L #if(WINVER >= 0x0400) #define LBS_NOSEL 0x4000L #endif /* WINVER >= 0x0400 */ #define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
// Measure item implementation relies on unique control/menu IDs void CWnd::OnMeasureItem(int /*nIDCtl*/, LPMEASUREITEMSTRUCT lpMeasureItemStruct) { if (lpMeasureItemStruct->CtlType == ODT_MENU) { // ... } else { CWnd* pChild = GetDescendantWindow(lpMeasureItemStruct->CtlID, TRUE); if (pChild != NULL && pChild->SendChildNotifyLastMsg()) return; // eaten by child } // not handled - do default Default(); }
GetDescendantWindow で求めた pChild が NULL のため CListBox::OnChildNotify から MeasureItem が呼ばれない?
呼ばれた時の lpMeasureItemStruct->itemHeight は,ODT_LISTBOX は 18 ,ODT_COMBOBOX は 20 .
デバッガで高さを設定すると,その高さになる.
OWNERDRAWVARIABLE は項目ごとに呼ばれるが,OWNERDRAWFIXED の時はうまくない?
結局,VC 6 などの場合にそうなる(逆にスクロール)様子.
コモンコントロール Ver.6 を使う様にすることで回避できる.
VC 6 exe などの場合は (VC6_app).exe.manifest ファイルを用意する.
視覚スタイルを有効にする
MFC コントロールのサブクラス化
今まで CWnd::SubclassDlgItem を使ってきたが,DDX_Control も同じ様なことをしているのではと思い調べてみた.
リストボックスをサブクラス化した時の OnInitDialog でのコード.
{ m_CtrlListFolder.SubclassDlgItem(IDC_LIST_FOLDER,this) ; m_CtrlListFolder.Init() ; m_CtrlListFolder.ResetContent() ; m_CtrlListFolder.SetItemHeight(30) ; }
IDC_LIST_FOLDER は,オーナードローリストボックス.
Inside Visual C++ や MFC による Windows 95 プログラミング を参考にしたと思う.
MFC のバージョンが上がると少しずつ変更が加わっている.
ソースは DlgData.cpp .VC 11 からは WinCore2.cpp .
MFC のソースは難しい.
かなり前の MSDN で次の内容を見つけた.
[MSVC] MFC を使用しての動的サブクラス化
DDX_Control でもいけそうな気もするが,…
コンソール AP での define
コンソール AP で Windows.h や Afx.h を読み込んだ時のエラーに対応するために i_def_aw.hxx を用意.
_AFXDLL で判断しているため「MFC のスタティックライブラリを使用」には対応できない.
// (VS8)\VC\AtlMFC\Include\AfxV_W32.h #ifdef _MSC_VER #ifdef _UNICODE #ifndef UNICODE #define UNICODE // UNICODE is used by Windows headers #endif #endif #ifdef UNICODE #ifndef _UNICODE #define _UNICODE // _UNICODE is used by C-runtime/MFC headers #endif #endif #endif #ifdef _MSC_VER #ifdef _AFXDLL #include <Afx.h> #else #include <Windows.h> #endif #endif #ifdef _MFC_VER // ... #endif
2022/07/27
その後,Windows.h を使用するコードを書いていてのまとめ.
#include "i_def_aw.hxx" // #include <Windows.h>
Win32 API のみで書いていて,MFC を利用する可能性がある場合は,この様に置き換え可能と思われる.
そうでない場合は,それらを利用するソースの先頭で Afx.h または i_def_aw.hxx をインクルードすれば良い.
https://dev.mish.work/wordpress/?s=i_def_aw
2022/08/01
今回書いた FVersion.hxx の様に MFC を利用しないものは,Windows.h の方が良い.
MFC コードが混在する場合 は,i_def_aw.hxx の利用と _MFC_VER での振り分けが良さそう.
日本語名ファイルのアップロード
次の所から日本語名のファイルをアップロードはできていたが,コードでの対応はうまくできていなかった.
https://itl.mish.work/…/upload.htm
そのため,アップロード時に 7 ビットのファイル名に変換することで対応していた.
これらのコードを書いたのは 3 年位前なので,その当時はまだよくわかっていなかった.
https://dev.mish.work/wordpress/2017/09/04/chttpfile-http-post/
またテクスチャファイル名などが日本語の場合はうまくいかないことも多かった.
最初,日本語名でそのままアップロードすると,いろいろ困った現象に…
PC から NAS 上のアップロード先のファイルが見えなくなってしまった.
一度スマートフォンの NAS 用のファイルマネージャから参照すると PC でも見えるようにはなった.
動作を見ると,サーバ側のコードは動作しているが,格納しているファイル名がうまく渡せていない.
ログなどを確認すると,デバッグ用 MBCS.exe でファイル名が「シフト JIS」のままになっていた.
送られるデータとしては次の所にあたる部分.
$_FILES[‘userfile’][‘name’]
これを UTF-8 にして渡す必要がある.
コードとしては次の所.
v_char Make_send_data (LPCTSTR upFile,LPCTSTR ___boundary) { v_char up_Data = v_c_Load(upFile) ; v_char sndData ; { tstring ct_boundary = ___boundary ; tstring file_img = ::QuotM_Add(_T("file_img")) ; tstring fileName = ::QuotM_Add(::Path_GetName(upFile)) ; tstring dataPre ; tstring dataPst ; dataPre+= CT_boundary__ + ct_boundary + C_CRLF ; dataPre+= CD_cd_f_d_n_ + file_img + CD_cd__fn_ ; dataPre+= fileName + C_CRLF ; dataPre+= CT_ct_a_o_s C_CRLF ; dataPre+= C_CRLF ; dataPst+= C_CRLF ; dataPst+= CT_boundary__ + ct_boundary + CT_boundary__ C_CRLF ; // v_char vc_pref = ::To_v_char(::To__string(dataPre.c_str())) ; v_char vc_pref = ::To_v_char(::To_UTF8 (dataPre.c_str())) ; v_char vc_post = ::To_v_char(::To__string(dataPst.c_str())) ; sndData.insert(sndData.end(),vc_pref.begin(),vc_pref.end()) ; sndData.insert(sndData.end(),up_Data.begin(),up_Data.end()) ; sndData.insert(sndData.end(),vc_post.begin(),vc_post.end()) ; } return sndData ; }
To__string でそのまま char の配列としていたものを UTF-8 にしてから char の配列に.
UpFile.hxx
quotm.hxx
2020/09/08
今度はサーバ側のコード.
本当はクライアントの CInternetSession のコンストラクタで与える User Agent .
UTF-8 でセットすれば良いのはわかるが,引数が LPCTSTR なのでどうすれば良いかわからず.
そのためサーバ側のログを出力する部分でうまく機能しないことがある.
Synology NAS では,一部文字化けするが特に問題なさそう.
ASUSTOR NAS や QNAP NAS では,20200908.txt の読み込み時に止まっている様子.
次の様に //IGNORE を付加して変換.
iconv API は iconv_open(_T("UTF-8//IGNORE")) iconv -f CP932 -t UTF-8//IGNORE 20200908.txt > 20200908.uf8 uconv -f CP932 -t UTF-8 -i 20200908.txt -o 20200908.uf8
CHttpFile アップロードの https 対応
以前作成した MFC によるアップロード の https 対応.
前回コードを書いた頃は https の環境が用意できなかったのでそのままと(http に)なっていた.
次の関数を呼び出して接続しているが,それぞれ引数が異なるものが用意されている.
CInternetSession::GetHttpConnection
CHttpConnection::OpenRequest
それらの引数に dwFlags があり,INTERNET_FLAG_SECURE が指定できる.
最初,両方の呼び出しに指定してみたが,CInternetSession::GetHttpConnection は指定しなくても通った.
CInternetSession session(userAgent.c_str()) ; CHttpConnection* pServer = NULL ; CHttpFile* pFile = NULL ; { // if (is_ssl) { // pServer = session.GetHttpConnection(serverN.c_str(),INTERNET_FLAG_SECURE,nPort) ; // } // else { pServer = session.GetHttpConnection(serverN.c_str(),nPort) ; // } if (pServer == NULL) { return false ; } } { if (is_ssl) { pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,php,NULL,1,NULL,_T("HTTP/1.1"),INTERNET_FLAG_SECURE) ; } else { pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,php) ; } if (pFile == NULL) { return false ; } // ... }
参考にさせてもらったのは次の所.
How to send HTTPS request using WinInet?
WinInet(MFC)を使ったhttpとhttps(自己証明書)
WinInet (MFC) の SSL通信 で 開発中に自己署名証明書を利用する場合のコード
std::fixed でアプリケーションエラー
先日やっていた計算式のコード.これをテストしていてエラーに.
エラーとなるコードの場所は数値を文字列に変換する所.
その部分だけを抜き出したコードは次の様なもの.
bool test (c_tstring& str_) { tstring str = str_ ; { TCHAR* endPtr = 0 ; double val = double(_tcstod(str.c_str(),&endPtr)) ; std::tout << std::fixed << val << std::endl ; // if (-1e50 < val && val < 1e50) { std::tout << std::fixed << val << std::endl ; } // else { std::tout << std::scientific << val << std::endl ; } } return true ; }
1e300 などの値を std::fixed で表示すると,限られた環境でビルドした exe でエラーになる.
エラーが確認できたのは VC 6 で MFC を使用しないでビルドしたもの.
VC 6 でも DLL でリンクしている場合は,ランタイムの DLL のバージョンにより大丈夫.
Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/mba_20/chk_big $ c++ chk_big.cpp -Wall Iwao@AS5202T:/volume1/home/Iwao/gcc_test/Test/mba_20/chk_big $ ./a.out value ? =1e10 10000000000.000000 value ? =1e100 10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104.000000 value ? =1e200 99999999999999996973312221251036165947450327545502362648241750950346848435554075534196338404706251868027512415973882408182135734368278484639385041047239877871023591066789981811181813306167128854888448.000000 value ? =1e300 1000000000000000052504760255204420248704468581108159154915854115511802457988908195786371375080447864043704443832883878176942523235360430575644792184786706982848387200926575803737830233794788090059368953234970799945081119038967640880074652742780142494579258788820056842838115669472196386865459400540160.000000 value ? =1e400 inf value ? =1e307 9999999999999999860310597602564577717002641838126363875249660735883565852672743849064846414228960666786379280392654615393353172850252103336275952370615397010730691664689375178569039851073146339641623266071126720011020169553304018596457812688561947201171488461172921822139066929851282122002676667750021070848.000000 value ? =1e308 100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000 value ? =1e309 inf value ? =-1e100 -10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104.000000 value ? =-1e307 -9999999999999999860310597602564577717002641838126363875249660735883565852672743849064846414228960666786379280392654615393353172850252103336275952370615397010730691664689375178569039851073146339641623266071126720011020169553304018596457812688561947201171488461172921822139066929851282122002676667750021070848.000000 value ? =-1e308 -100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000 value ? =-1e309 -inf value ? =1.e-100 0.000000 value ? =1.e-300 0.000000
#pragma message (” ~ “) の利用
先日からやっているコードの解析部分を単体テスト用に分割していると,
--------------------構成: prs_frml - Win32 Debug-------------------- コンパイル中... prs_frml.cpp c:\program files\microsoft visual studio\vc98\mfc\include\afxv_w32.h(14) : fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h> cl.exe の実行エラー prs_frml.exe - エラー 1、警告 0
「パッと見」でわかる時は良いが,今回はわかり難い.
そんな時に私が場所を限定していく手順.
次の様に影響していそうな所に #pragma message (” ~ “) を追加.
#pragma message ("pass 1") #include "StrAryTo.hxx" #pragma message ("pass 2") #ifdef _MSC_VER #ifdef _AFXDLL #else #ifndef afxDump #define afxDump std::terr #endif #endif #endif #pragma message ("pass 3")
今回は次の様になったので StrAyTo.hxx が原因とわかった.
pass 1 c:\program files\microsoft visual studio\vc98\mfc\include\afxv_w32.h(14) : fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h>
StrAryTo.hxx は CStringArray と std::vector<tstring> を相互変換するコード.
インクルードから外すことで対応.
MFC を使用しているソースなどの対応方法は次の所.
https://dev.mish.work/wordpress/2019/04/05/c1189-windows-h-already-included/
C4244: ‘初期化中’: ‘INT_PTR’ から …
VC 2002 より前に作成した「ダイアログベース」のプロジェクトの場合 x64 対応に変更すると
XxxApp.cpp(73): warning C4244: ‘初期化中’: ‘INT_PTR’ から ‘int’ への変換です。データが失われる可能性があります。
生成されるスケルトンでは,アプリケーションクラスのダイアログの部分が次の様になっている.
CFBXtoMDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK) {
}
else if (nResponse == IDCANCEL) {
}
x86,x64 共に warning などを出なくするには,int となっている部分を INT_PTR に変更 する.
「MFC を使用しない」のエラー
’91 年に C で作成して,’95 年頃に C++ で書き直したコード.
その頃は MFC なしでも動作するようにコードを書いていた.
が,’06 頃の UNICODE 化で MFC に依存するようになってしまっている.
main 関数だけ用意して,対象の cpp をインクルードしてビルドすると,
--------------------構成: t_calc - Win32 Debug-------------------- コンパイル中... t_calc.cpp リンク中... nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) はすでに libcpd.lib(delop.obj) で定義されています nafxcwd.lib(thrdcore.obj) : error LNK2001: 外部シンボル "__endthreadex" は未解決です nafxcwd.lib(thrdcore.obj) : error LNK2001: 外部シンボル "__beginthreadex" は未解決です C:\Temp\Debug\Calc\t_calc\Debug.060/t_calc.exe : fatal error LNK1120: 外部参照 2 が未解決です。 link.exe の実行エラー t_calc.exe - エラー 4、警告 0
どこかで Afx.h など MFC のコードをインクルードしてしまっている.
インクルードを順に辿るとすぐ見つかるが,どう修正するか悩むところ.
MFC を必要とする場合は今まで通りで,不要な場合は新しいコードに切り替えるか?
#ifdef _MFC_VER #include <Afx.h> #else #include "_s_func.hxx" #endif
ある程度必要なコードは特定できたがまだ書き直してないコードもありそう.
_MFC_VER で切り替えようと思ったが,コンソール AP ではうまく機能しない.
How to detect “Use MFC” in preprocessor
_MFC_VER は Afx.h の中で間接的(AfxVer_.h)に定義されている.
使えるのは _AFXDLL のみ?
次の様な感じ?
#ifdef _MSC_VER #ifdef _AFXDLL #include <Afx.h> #else #include <Windows.h> #endif #endif
2020/02/14
ヘッダファイルで CString などを使用しているコードの部分は
#ifdef _MFC_VER CString ChangeString (LPCTSTR str) ; #endif
2020/09/25
コンソール AP での define
VC 6 C2059 C2091 C2809 C2954
2001/11 作成のプロジェクトをビルドしたらよくわからないエラー.
--------------------構成: MsgStCon - Win32 Debug-------------------- コンパイル中... MsgStCon.cpp c:\program files\microsoft visual studio\vc98\include\memory(16) : error C2059: 構文エラー : 'string' c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2091: 関数は関数を返せません。 c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2809: 'operator new' に仮引数リストがありません。 c:\program files\microsoft visual studio\vc98\include\memory(20) : error C2954: テンプレートの定義はネストできません。 cl.exe の実行エラー MsgStCon.obj - エラー 4、警告 0
ソースの先頭付近に #include <memory> を追加.
#include "StdAfx.h" #include "MsgStCon.h" #include <memory> // ① OK #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #include <memory> // ② NG // ...
②の位置では現象は変わらず.①の位置に追加する必要がある.
2023/03/24
error C2061 , C2091 , C2809 , C2556
CEdit で文字列の最後を表示させる
エディットボックスに文字列が入りきらない場合に,文字列の最後の方を表示させる方法
例えば次のように UpdateData(FALSE) を呼び出すと CEdit::GetSel では開始位置と終了位置が 0 で戻される.
m_OutFolder = Copy_ccc.GetTarget().c_str() ; UpdateData(FALSE) ;
CEdit::SetSel で文字列の長さを指定することにより最後の位置を選択してその部分が表示されるようにする.
m_OutFolder = Copy_ccc.GetTarget().c_str() ; UpdateData(FALSE) ; int start = m_OutFolder.GetLength() ; int end = m_OutFolder.GetLength() ; m_CtrlOutFolder.SetSel(start,end) ;
int start = m_OutFolder.GetLength()-1 ; int end = m_OutFolder.GetLength()-0 ;
EN_NOHIDESEL を有効にする.
SDI exe で変換後ドキュメントを開く
SDI exe で,変換後のデータをそのまま開きたかった.
OnOpenDocument で開くことは可能だが,幾つかうまくない所がある.
CDocument の OnOpenDocument 前後の動作をデバッガで追いかけると,ビューの初期化が足りない.
CView* を求めて OnInitialUpdate で対応.
void CX__Doc::OnConvert() { if (GetPathName().IsEmpty()) { return ; } tstring new_name ; { // ... ::G3_to_NEW(...,new_name.c_str()) ; } { OnNewDocument () ; OnOpenDocument(new_name.c_str()) ; SetPathName (new_name.c_str()) ; { CFrameWnd* frame = (CFrameWnd*)AfxGetMainWnd() ; if (frame != NULL) { CView* view = frame->GetActiveView() ; if (view != NULL) { view->OnInitialUpdate() ; } } } } }
error C1189: #error: Please use /MD
プロジェクトの設定で「スタティック ライブラリで MFC を使用する」から「共有 DLL で MFC を使う」に変更すると,次のエラーになることがある.
—— ビルド開始: プロジェクト: MkCmf, 構成: Release Win32 ——
StdAfx.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.22.27905\atlmfc\include\afxver_.h(77,1): error C1189: #error: Please use the /MD switch for _AFXDLL builds
プロジェクト “MkCmf142.vcxproj” のビルドが終了しました — 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
対応方法はエラーメッセージにある様に
「マルチスレッド(/MT)」から「マルチスレッド DLL(/MD)」に変更する.
同様に「共有 DLL で MFC を使う」から「スタティック ライブラリで MFC を使用する」に変更した場合.
—— ビルド開始: プロジェクト: AsHVR, 構成: Release Win32 ——
StdAfx.cpp
c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.16.27023\atlmfc\include\afx.h(24): fatal error C1189: #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
プロジェクト “AsHVR142.vcxproj” のビルドが終了しました — 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
この場合は「マルチスレッド(/MT)」に変更する.
2021/04/01
それぞれの設定に対応するには「<親またはプロジェクトの既定値から継承>」とすれば良さそう.
次のエラーの場合はこちら.
fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h>
Win10 に入っている MFC*.dll
MFC の DLL に関して調べていて,
Win10 では幾つかの MFC DLL がインストールされているという記述を見つけたので調べてみました.
VirtualBox で仮想環境を作成して,Win10 Pro 1903 をインストール.
インストールされているものは仮想マシン用のツール.
このような環境で C ドライブを mfc*.dll で検索すると,見つかるのは前から存在するもの.
mfc40.dll mfc40u.dll mfc42.dll mfc42u.dll
Win10 のバージョンによるのかどうかわかりませんが,
OS のみのインストール状態では mfc140u.dll は入っていないようです.
私の方で MFC dll をダウンロードするページへのリンクをまとめています.
https://i-tools.mish.work/2017/05/mfc140udll.html
https://jml.mish.work/index.php/cpp/ref-vcredist-xxx-exe.html
2019/06/15
msvc???.dll などは入っていたのでその画面コピーです.
2022/10/06
Win11 に入っている MFC*.DLL