ホーム » MFC (ページ 6)

MFC」カテゴリーアーカイブ

2024年5月
 1234
567891011
12131415161718
19202122232425
262728293031  

カテゴリー

アーカイブ

ブログ統計情報

  • 80,865 アクセス



CView の OnFilePrint を抜き出し

OnFilePrint の関係を DH_Print クラスとして抜き出しました.
ダイアログベースの exe や,ビューの表示対象と異なるオブジェクトの印刷などに利用できると思います.
利用方法はこんな感じ.

class	PrintTest	:	public	DH_Print	{
public:
  virtual	void	OnPrint	  (CDC* pDC,	CPrintInfo* pInfo)	{
    CRect	rect = pInfo->m_rectDraw ;
    {
      pDC->TextOut(0,0,_T("ここが印刷のためのコードです.")) ;
      }
    return	;
    }
  virtual	BOOL	OnPreparePrinting (	CPrintInfo* pInfo)	{
    pInfo->SetMaxPage(5) ;
    return	DoPreparePrinting(pInfo) ;
    }
  virtual	CString	GetDocumentTitle  (void)	{
    return	_T("通常はドキュメント名を戻します.") ;
    }
  } ;

印刷が押されると,

void CAboutDlg::OnPrint() 
{
  PrintTest	pt ;
  if (pt.OnFilePrint()) {
    OnOK() ;
    }
  }

Print.zip
Print
マルチページ ドキュメント


2020/07/13 Google ドライブ上の Print.zip へのリンク
Print.zip


2020/12/17 公開しているファイルだけでは利用できなかったので修正
Print_2020_12.zip
クラス名 Print は DH_Print に変更.
印刷時のデフォルトのドキュメント名を ” DH_Print : %Y/%m/%d %H:%M:%S ” に変更.


DH_Print クラスを利用したサンプル.
DH_Print クラスのサンプル EMF の印刷
PrtMF_2020_12.zip
DH_Print 利用のソースが zip の中にあり.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

DDV を働かせたい

あまり DDV は使用しないが,数値で簡単な範囲チェックをやりたかった.
最大文字数などは指定しておけば勝手にやってくれるが,値のチェックはそうではない.

適当な(チェックしたい)タイミングで UpdateData(TRUE) を呼んでやればよい.
例えば,
void CXxxxDlg::OnChangeXxx() { UpdateData(TRUE) ; }
EN_UPDATE とどちらが良いかは不明.

本当は範囲を超えた時の入力をはじきたいが,それは簡単にはできなかった.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

Copy SrcFolder\*.txt DstFolder

あるフォルダの複数ファイルのコピーと移動.
 Files_Copy_or_Move を直接利用するのではなく,FolderCopyFiles , FolderMoveFiles を利用します.
//*******************************************************************************
// 関数名 :あるフォルダ直下のファイルのコピーと移動
// 作成日 :’11/11/04
//*******************************************************************************
BOOL Files_Copy_or_Move (LPCTSTR src_Name,LPCTSTR dstPath,const BOOL isDelSrc,const BOOL exist)
{
  CString srcPath = src_Name ;
  CString srcName = _T(“*.*”) ;
  if (CString(srcPath).IsEmpty()) { return FALSE ; }
  if (!::FileIsDirectory(src_Name)) {
    srcPath = ::GetFileDir (src_Name) ;
    srcName = ::GetFileName (src_Name) ;
    }
  if (srcPath == dstPath) { return FALSE ; }
  if (::FileIsNothing(srcPath)) { return FALSE ; } // 元のフォルダが存在しない
  if (::FileIsNothing(dstPath)) {
    if (!::CreateFolder(dstPath)) { return FALSE ; }
    }
  {
    CStringArray srcFiles ;
    ::FolderEnumFiles(srcPath,&srcFiles,srcName) ;
    for (int index=0 ; index<srcFiles.GetSize() ; index++) {
      CString srcFPath = srcFiles[index] ;
      CString srcFName = ::GetFileName(srcFPath) ;
      CString newFName = ::FolderAddLastSP(dstPath) + srcFName ;
      if (!::CopyFile(srcFPath,newFName,exist)) {
        continue ;
        }
      if (isDelSrc) { // 元のファイルは削除? (移動の場合?)
        CFile::Remove(srcFPath) ;
        }
      }
    }
  return TRUE ;
  }

inline BOOL FolderCopyFiles (LPCTSTR srcName, LPCTSTR dstPath, const BOOL exist)
{ return Files_Copy_or_Move ( srcName, dstPath, FALSE, exist) ; }
inline BOOL FolderMoveFiles (LPCTSTR srcName, LPCTSTR dstPath, const BOOL exist=FALSE)
{ return Files_Copy_or_Move ( srcName, dstPath, TRUE, exist) ; }

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

GetLastError と FormatMessage

以前,以下を作成していた(Error.hxx)

inline	CString	Error::FormatMessage(const DWORD error)
{
	CString	message ;
	LPVOID	lpMessageBuffer = NULL ;
	if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,error,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
		(LPTSTR)&lpMessageBuffer,0,NULL)) {
		message = LPTSTR(lpMessageBuffer) ;
		::LocalFree(lpMessageBuffer) ;
		}
	return	message ;
	}
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

FindNoCase

同じ関数を作ってしまったので,...
CharFnc.hxx より
//*******************************************************************************
// 関数名 :大文字/小文字を区別せずに検索
// 作成日 :’11/09/07
//*******************************************************************************
inline
int FindNoCase (LPCTSTR str1,LPCTSTR str2)
{
  CString fStr1 = str1 ;
  int fIndex = fStr1.Find(str2) ;
  if (fIndex >= 0) { return fIndex ; } // 大文字/小文字を区別して見つかった?
  CString fStr2 = str2 ;
  fStr1.MakeLower() ;
  fStr2.MakeLower() ;
  return fStr1.Find(fStr2) ; // 大文字/小文字を区別せずに(小文字にして)検索
  }

他にも,
PathName.hxx
PathName.hxx
//*******************************************************************************
// 関数名 :ファイル拡張子取得(text.DAT->dat) 小文字で
// 作成日 :’11/06/09
//*******************************************************************************
inline
CString GetFileExtLow (LPCTSTR pathName)
{
  CString ext = ::GetFileExt(pathName) ;
  ext.MakeLower() ;
  return ext ;
  }


StringFn.hxx

stringfn.hxx

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

BDH_Modify クラスを用意

BDH_Modify クラスを用意しました.
 class BDH_Modify {
 public:
   BDH_Modify () { Modified = FALSE ; }
 public:
  virtual BOOL IsModified (void) const { return Modified ; }
  virtual BOOL SetModifiedFlag (const BOOL mod=TRUE) { Modified = mod ; return TRUE ; }
  virtual BOOL CanClose (void) { return SaveModified() ; }
 public:
  virtual CString GetPathName (void) const { return _T(“ファイル”) ; }
  virtual BOOL DoFileSave (void) { return FALSE ; }
 public:
  virtual BOOL SaveModified (void) ;
 protected:
  BOOL Modified ;
  } ;

 inline
 BOOL BDH_Modify::SaveModified (void)
 {
  if (!IsModified()) { return TRUE ; }
  CString name = GetPathName() ;
  if (name.Find(‘\\’) >= 0) {
   name = ::GetFileName(name) ;
   }
  // VC98\MFC\SRC\DocCore.cpp CDocument::SaveModified() より
  CString prompt ;
  AfxFormatString1(prompt,AFX_IDP_ASK_TO_SAVE,name) ;
  switch (AfxMessageBox(prompt,MB_YESNOCANCEL,AFX_IDP_ASK_TO_SAVE)) {
   case IDCANCEL: return FALSE ; break ;
   case IDYES : if (!DoFileSave()) { return FALSE ; } break ;
   case IDNO : break ;
   default : break ;
   }
   return TRUE ;
  }

ダイアログベースなどで利用するために作成しました.
以下の様に利用しています.
 #include “BDH_Mod.hxx”
 class BDModCSV : public BDocCSV , public BDH_Modify {
 public:
  virtual BOOL Clear (void) { SetModifiedFlag(FALSE) ; return BDocCSV::Clear() ; }
 public:
  virtual void Serialize (CArchive& ar) { SetModifiedFlag(FALSE) ; BDocCSV::Serialize(ar) ; }
  } ;

 class Masters : public BDModCSV
 {
  // …
  virtual CString GetPathName (void) const { return GetFilePath() ; }
  virtual BOOL DoFileSave (void) { return FileWrite(GetFilePath()) ; }
  } ;

 BOOL Masters::AddMaster1 (Master* reg)
 {
  SetModifiedFlag(TRUE) ;
  // …
  }

 void CEditCNDlg::OnCancel()
 {
  Masters* masters = Mast_S->GetSelected() ;
  if (masters != NULL && !masters->CanClose()) { return ; }
  CDialog::OnCancel();
  }

BDH_Modify クラス

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

UNICODE と VC6 → VC8 一部修正

UNICODE と VC6 → VC8  2009/12

VC6 UNICODE

wWinMainCRTStartup

VC6 → VC8

http://cid-535f5973454c1292.skydrive.live.com/self.aspx/.Public/MFC/VC6%e2%86%92VC8.txt

「全般」-「出力ディレクトリ」,「中間ディレクトリ」 .\$(ConfigurationName)
「プリコンパイル済みヘッダファイル」 $(IntDir)/$(TargetName).pch
「C/C++」-「出力ファイル」
 「ASMリスト...」
 「オブジェクト...」
 「プログラムデータベース...」
$(IntDir)/
「リンカ」-「全般」の「出力ファイル」 $(OutDir)/$(ProjectName).exe
リンカ」-「デバッグ」
 「プログラムデータベースファイルの生成」
$(OutDir)/$(ProjectName).pdb
「リソース」-「全般」の「リソースファイル名」 $(IntDir)/$(InputName).res
「MIDL」-「出力」の「タイプライブラリ」 $(IntDir)/$(ProjectName).tlb
「ブラウザ情報」-「全般」の「出力ファイル」 $(OutDir)/$(ProjectName).bsc

 
https://dev.mish.work/Iwao/Doc/other/vs/

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CListCtrl の列数の取得

CListCtrl の列数の取得

  int		colCount = 0 ;
  // C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\WinCtrl6.cpp
  // CListCtrl::GetColumnOrderArray より
  {
    CHeaderCtrl*	pCtrl = ctrl->GetHeaderCtrl() ;
    if (pCtrl != NULL)	{	colCount = pCtrl->GetItemCount() ;	}
    }

CListCtrl::GetItemCount では行数
CListCtrl レポート形式

Is this 投稿 useful? Useful Useless 1 of 1 people say this 投稿 is useful.

CArray&saAry

CStringArray の配列を使用する時の制限?

c:\program files\microsoft visual studio\vc98\mfc\include\afxtempl.h(86) : error C2582: ‘operator ” 関数は ” 内では使用できません。
c:\program files\microsoft visual studio\vc98\mfc\include\afxtempl.h(406) : コンパイルされたクラスのテンプレートのインスタンス化 ‘void __stdcall CopyElements(class CStringArray *,const class CStringArray *,int)’ の参照を確認してください
  以下の様なコードでコメントにした Copy があると,エラーとなる.
  {
    CArray<CStringArray,CStringArray> saAry ;
    CArray<CStringArray,CStringArray> saA ;
  // saAry.Copy(saA) ;
    }

他にもいろいろとエラーになったが,うまく抜き出せなかった.
関数などの引数として与える時に,最初 const としていたためか?
const を外して,それなりにコードを書けば通るようになったみたい.
これらを利用して書いたコードは,ListBD_C.hxx

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CString::ReleaseBuffer で Assert

CString::GetBuffer を使用して,ReleaseBuffer を忘れているバグがあった.
現象は,内容をコピーした別の CString で ReleaseBuffer した時にアサート.
—————————
Microsoft Visual C++ Debug Library
—————————
Debug Assertion Failed!
Program: …\…\TInet\Debug.060\TInet.exe
File: strcore.cpp
Line: 512
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)
—————————
CString::ReleaseBuffer で Assert

他にも,GetLength で 0 になる.
CString::GetLength()  で 0 になる

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

DoDragDrop ですぐに抜ける?

以下の様なコードで,COleDataSource::DoDragDrop の部分がすぐ抜ける.
  CStringArray sa ;
  ::ListBoxToStringArray(m_DropList,&sa,TRUE) ;
  {
    CByteArray ba ;
    ::StringArrayToString2Z(sa,&ba) ;
    int len = ba.GetSize() ;
    HDROP hDrop = (HDROP)::GlobalAlloc(GHND,sizeof(DROPFILES) + len + sizeof(TCHAR)) ;
    if (hDrop == NULL) { return ; }
    LPDROPFILES lpdf = (LPDROPFILES)::GlobalLock(hDrop) ;
    lpdf->pFiles= sizeof(DROPFILES) ;
    lpdf->pt.x = 0 ;
    lpdf->pt.y = 0 ;
    lpdf->fNC = FALSE ;
    lpdf->fWide = FALSE ;
    #ifdef _UNICODE
    lpdf->fWide = TRUE ;
    #endif
    LPCTSTR lpFileNames = LPCTSTR(LPCSTR(lpdf)+lpdf->pFiles) ;
    memmove(LPVOID(lpFileNames),ba.GetData(),len) ;
    ::GlobalUnlock(hDrop) ;
    {
      COleDataSource* ods = new COleDataSource ;
      ods->CacheGlobalData(CF_HDROP,hDrop) ;
      ods->DoDragDrop() ;
      delete ods ;
      }
    }

AfxOleInit() を呼出していなかった.


[VC50] Windows 95 標準コントロールのドラッグアンドドロップサンプル 
http://support.microsoft.com/kb/152092/ja


2014/08/11 追記
上のコードで,delete ods はうまくない.
データ オブジェクトとデータ ソース : 作成と破棄

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CInternetFile::ReadString

CInternetFile::ReadString
CInternetFile::ReadString
VC 6 UNICODE.exe で,文字化けと,中身がうまく処理されない.MBCS.exe はOK.
文字化けは,CHAR から TCHAR への変換を正しく処理することにより対応.
それでも,まだ改行の位置で戻らず,終端も正しくない(デバッグ版ではゴミ ‘0xCD’ が入る).
どうも,VC 6 や 7 では,うまく処理できないみたい.VC 8 では期待した動作と思われる.

  CHttpConnection* pServer = pServer = session.GetHttpConnection (svrName) ;
  CHttpFile* pFile = pServer->OpenRequest (CHttpConnection::HTTP_VERB_GET,name) ;
  pFile-> SendRequest () ;
  {
    CString buf ;
    while (pFile->ReadString(buf)) {
      CString tmp = ::ToStringTC(LPCSTR(LPCTSTR(buf))) ;
      rBuf.Add(tmp) ;
      }
    ::StringArrayToString(rBuf,rData) ;
    }

http://support.microsoft.com/kb/329071
Microsoft KB Archive/329071
 PRB: CInternetFile::ReadString Does Not Convert Non-Unicode Text to Unicode Text


2019/01/31 LPCSTR , LPCWSTR からの変換
CRT_MBWC.hxx
tstrmbwc.hxx


2022/09/09 CHttpFile Read String

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

MS11-025 その後

以前,KB2465367 などの影響を受けたが,その対応版 KB2538218 のコードの抜粋
typedef BOOL (WINAPI *PFNFINDACTCTXSECTIONSTRING)(DWORD, const GUID *, ULONG, LPCTSTR, PACTCTX_SECTION_KEYED_DATA);
static HINSTANCE _AfxLoadLangDLL(LPCTSTR pszFormat, LPCTSTR pszPath, LCID lcid)
{
 TCHAR szLangDLL[_MAX_PATH+14];
 TCHAR szLangCode[4];
 HINSTANCE hInstance = NULL;
 if (lcid == LOCALE_SYSTEM_DEFAULT) {
  Checked::tcscpy_s(szLangCode, _countof(szLangCode), _T("LOC"));
  }
 else {
  int nResult;
  nResult = ::GetLocaleInfo(lcid, LOCALE_SABBREVLANGNAME, szLangCode, 4);
  if (nResult == 0)
    return NULL;
  ASSERT( nResult == 4 );
  }
 int ret;
 ATL_CRT_ERRORCHECK_SPRINTF(ret = _sntprintf_s(szLangDLL,_countof(szLangDLL),_countof(szLangDLL)-1,pszFormat,pszPath,szLangCode));
 if(ret == -1 || ret >= _countof(szLangDLL)) {
  ASSERT(FALSE);
  return NULL;
  }
 TCHAR *pszFilename = ::PathFindFileName(szLangDLL);
 ACTCTX_SECTION_KEYED_DATA data = {sizeof(data)};
 HMODULE hKernel = GetModuleHandle(_T("KERNEL32"));
 PFNFINDACTCTXSECTIONSTRING pfnFindActCtxSectionString = NULL;
 if (hKernel != NULL) {
  #ifdef _UNICODE
   pfnFindActCtxSectionString = (PFNFINDACTCTXSECTIONSTRING)GetProcAddress(hKernel, "FindActCtxSectionStringW");
  #else
   pfnFindActCtxSectionString = (PFNFINDACTCTXSECTIONSTRING)GetProcAddress(hKernel, "FindActCtxSectionStringA");
  #endif
  }
 if (pfnFindActCtxSectionString &&
 pfnFindActCtxSectionString(0, NULL, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, pszFilename, &data)) {
  // Load using the dll name only…
  hInstance = ::LoadLibraryEx(pszFilename, NULL, 0);
  }
 else {
  // Load using the full path…
  hInstance = ::LoadLibraryEx(szLangDLL, NULL, 0);
  }
 return hInstance;
 }

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

List.exe 起動時,アプリケーションエラー

以前は通っていたデバッグ用 exe をビルドしたら,起動時にアプリケーションエラーになってしまった.

原因は,アプリケーションクラス内に確保された Profile .
なぜ宣言されていたのかは今となっては不明.
ListApp.h 内をコメントにして OK .

以下が初期化される前に Profile::GetInt が通ることによりエラーとなる.
_CriticalS_ Profile::CS ;

またこのタイミング(アプリケーションクラスのコンストラクタ)では,SetRegistoryKey が指定されていないので,Profile クラスを利用すること自体がうまくないと思われる.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

DECLARE_SERIAL を忘れると…

IMPLEMENT_SERIAL (T_BaseDoc, CObject,0) の所で
C:\…\T_BDDoc.cpp(63) : error C2039: ‘CreateObject’ : ‘T_BaseDoc’ のメンバではありません。
    c:\…\t_bd_.hpp(28) : ‘T_BaseDoc’ の宣言を確認してください。
C:\…\T_BDDoc.cpp(63) : error C2509: ‘_GetBaseClass’ : このメンバ関数は、’T_BaseDoc’ クラス内で宣言されていません。
C:\…\T_BDDoc.cpp(63) : error C2039: ‘classT_BaseDoc’ : ‘T_BaseDoc’ のメンバではありません。
    c:\…\t_bd_.hpp(28) : ‘T_BaseDoc’ の宣言を確認してください。
C:\…\T_BDDoc.cpp(63) : error C2039: ‘CreateObject’ : ‘T_BaseDoc’ のメンバではありません。
    c:\…\t_bd_.hpp(28) : ‘T_BaseDoc’ の宣言を確認してください。
C:\…\T_BDDoc.cpp(63) : error C2509: ‘GetRuntimeClass’ : このメンバ関数は、’T_BaseDoc’ クラス内で宣言されていません。
C:\…\T_BDDoc.cpp(63) : error C2039: ‘classT_BaseDoc’ : ‘T_BaseDoc’ のメンバではありません。
    c:\…\t_bd_.hpp(28) : ‘T_BaseDoc’ の宣言を確認してください。
C:\…\T_BDDoc.cpp(63) : error C2039: ‘classT_BaseDoc’ : ‘T_BaseDoc’ のメンバではありません。
    c:\…\t_bd_.hpp(28) : ‘T_BaseDoc’ の宣言を確認してください。
 

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

MS11-025 の影響?

2011/06/16 追記
2011/06/15 に MS11-025 が更新されたので,以下は古い情報になります.


 
どちらかというと,以下の影響
Microsoft Visual C++ 2005 Service Pack 1 再頒布可能パッケージ (KB2467175)
Microsoft Visual C++ 2008 Service Pack 1 再頒布可能パッケージ (KB2467174)
MS11-025

Win 7 で,AFX_IDS_~ の表示が英語になってしまう.
 Open , Save As , 印刷プレビューのボタン
 All Files (*.*)
 Failed to create empty document.
 C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\l.jpn
MS11-025 「開く」ダイアログへの影響
MS11-025 印刷プレビューのボタン

AppCore.cpp の _AfxLoadLangDLL と思うが,うまく確かめられない.
ここが呼ばれる前のコードを切り出して lcid は 1041 で,JPN が求まっている所までは確認.

デバッグ版では,MFC90JPN.dll がロードされている(デバッガやリソースモニターで確認).
C:\Windows\WinSxS\x86_microsoft.vc90.mfcloc_1fc8b3b9a1e18e3b_9.0.30729.5570_none_4977a39175471b31\MFC90JPN.DLL

リリース版に,デバッグ情報を付加して動作を見ると
SXS: Invalid parameter(s) passed to FindActCtxSection*()
 dwFlags = 0x00000001
 ReturnedData = 0018F58C
  ->cbSize = 0

FindActCtxSection を検索すると,
Visual C++ MFC and ATL FindActCtxSection
そこからのリンクは Martin’s Blog 自動翻訳


_AfxLoadLangDLL のコードを比べると,
Microsoft Visual Studio 2005 Service Pack 1 (KB2465367) 適用前
static HINSTANCE _AfxLoadLangDLL(LPCTSTR pszFormat, LPCTSTR pszPath, LCID lcid)
{
 …
 int ret;
 ATL_CRT_ERRORCHECK_SPRINTF(ret = _sntprintf_s(szLangDLL,_countof(szLangDLL),
     _countof(szLangDLL)-1,pszFormat,pszPath,szLangCode));
 if(ret == -1 || ret >= _countof(szLangDLL)) {
  ASSERT(FALSE);
  return NULL;
  }
 hInstance = ::LoadLibrary(szLangDLL);
 return hInstance;
 }

適用後
static HINSTANCE _AfxLoadLangDLL(LPCTSTR pszFormat, LPCTSTR pszPath, LCID lcid)
{
 …
 int ret;
 ATL_CRT_ERRORCHECK_SPRINTF(ret = _sntprintf_s(szLangDLL,_countof(szLangDLL),
     _countof(szLangDLL)-1,pszFormat,pszPath,szLangCode));
 if(ret == -1 || ret >= _countof(szLangDLL)) {
  ASSERT(FALSE);
  return NULL;
  }
 TCHAR *pszFilename = ::PathFindFileName(szLangDLL);
 ACTCTX_SECTION_KEYED_DATA data;
 if (FindActCtxSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
    ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,pszFilename, &data) ) {
  // Load using the dll name only…
  hInstance = ::LoadLibraryEx(pszFilename, NULL, LOAD_LIBRARY_AS_DATAFILE);
  }
 else {    // Load using the full path…
  hInstance = ::LoadLibraryEx(szLangDLL, NULL, 0);
  }

 return hInstance;
 }

FindActCtxSectionString によって,Win 2K では動作しなくなるらしい.


2011/05/10 追記
Ted’s Blog Fixing problems with FindActCtxSectionString in MFC security updates
 static.exe での Win2K 対応と,ACTCTX_SECTION_KEYED_DATA の初期化など
 
比べてもあまり意味はないが,VC 2010 では
static HINSTANCE _AfxLoadLangDLL(LPCTSTR pszFormat, LPCTSTR pszPath, LCID lcid)
{
  TCHAR szLangDLL[_MAX_PATH+14];
  TCHAR szLangCode[4];
  HINSTANCE hInstance;
  if (lcid == LOCALE_SYSTEM_DEFAULT) {
    Checked::tcscpy_s(szLangCode, _countof(szLangCode), _T(“LOC”));
    }
  else {
    int nResult;
    nResult = ::GetLocaleInfo(lcid, LOCALE_SABBREVLANGNAME, szLangCode, 4);
    if (nResult == 0)
      return NULL;
    ASSERT( nResult == 4 );
    }
  int ret;
  ATL_CRT_ERRORCHECK_SPRINTF(ret = _sntprintf_s(szLangDLL,_countof(szLangDLL),
               _countof(szLangDLL)-1,pszFormat,pszPath,szLangCode));
  if(ret == -1 || ret >= _countof(szLangDLL)) {
    ASSERT(FALSE);
    return NULL;
    }
  hInstance = ::LoadLibraryEx(szLangDLL, NULL, 0);
  return hInstance;
  }  

pszPath は “C:\Windows\system32\” になっている.
 

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

VC 2010 ドキュメントのプレビュー

サムネイル void CXxxDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
プレビュー void CXxxView::OnDraw(CDC* pDC)

プレビューの方はそれなりに動作している様だが,サムネイルの方はちょっと動きが違う様な?

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

ウィンドウを透明に

SetLayeredWindowAttributes

#ifndef _INC_H_HELP_USER_DLL
#define _INC_H_HELP_USER_DLL

#include <WinUser.h>

////
//*******************************************************************************
// 関数名 :SetLayeredWindowAttributes
// 作成日 :’11/01/26
//*******************************************************************************
// C:\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\Include\WinUser.h より

#ifndef LWA_COLORKEY

WINUSERAPI BOOL WINAPI SetLayeredWindowAttributes(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags) ;
#define LWA_COLORKEY 0x00000001
#define LWA_ALPHA 0x00000002

inline
BOOL Hlp_SetLayeredWindowAttributes (HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags)
{
  HMODULE hDll = ::LoadLibrary(_T(“User32.dll”)) ;
  if (hDll == NULL) { return FALSE ; }
  HRESULT (WINAPI *pfSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD) = NULL ;
  (FARPROC&)pfSetLayeredWindowAttributes = ::GetProcAddress(hDll,(“SetLayeredWindowAttributes”)) ;
  BOOL res = FALSE ;
  if (pfSetLayeredWindowAttributes != NULL) {
    res = pfSetLayeredWindowAttributes(hwnd,crKey,bAlpha,dwFlags) ;
    }
  ::FreeLibrary(hDll) ;
  return res ;
  }

#define Use_Help

#endif

////
//*******************************************************************************
// 関数名 :SetLayeredWindowAttributes
// 作成日 :’11/01/26
//*******************************************************************************

#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
#endif

inline
BOOL SetLayeredWindowAttributes(CWnd*wnd,COLORREF key,BYTE alpha=128,DWORD flags=LWA_COLORKEY)
{
  if (wnd == NULL) { return FALSE ; }
  HWND hwnd = wnd->GetSafeHwnd() ;
  if (hwnd == NULL) { return FALSE ; }
  BOOL result = FALSE ;
  LONG exStyle=::GetWindowLong(hwnd,GWL_EXSTYLE) ;
  ::SetWindowLong(hwnd,GWL_EXSTYLE,exStyle|WS_EX_LAYERED) ;
  #ifdef Use_Help
    result = ::Hlp_SetLayeredWindowAttributes(hwnd,key,alpha,flags) ;
  #else
    result = ::SetLayeredWindowAttributes(hwnd,key,alpha,flags) ;
  #endif
  return result ;
  }

#endif

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

MFC 6 で CHARFORMATW

SetSelectionCharFormat では,CHARFORMATA になっている様なので

CString faceName= FontFace.GetFaceName() ;
{
  CHARRANGE selCR ;
  m_CtrlRichEdit.GetSel(selCR) ;
  {
    m_CtrlRichEdit.SetSel(0,-1) ;
    #ifdef _UNICODE
      CHARFORMATW cf ; ::ZeroMemory(&cf,sizeof(CHARFORMATW)) ; cf.cbSize = sizeof(CHARFORMATW) ;
    #else
      CHARFORMAT cf ; ::ZeroMemory(&cf,sizeof(CHARFORMAT)) ; cf.cbSize = sizeof(CHARFORMAT) ;
    #endif
    ::TcsNCpy(cf.szFaceName,LF_FACESIZE-1,faceName,LF_FACESIZE-1) ;
    cf.dwMask = CFM_FACE ;
    #ifdef _UNICODE
      m_CtrlRichEdit.SendMessage(EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cf) ;
    #else
      m_CtrlRichEdit.SetSelectionCharFormat(cf) ;
    #endif
    }
  m_CtrlRichEdit.SetSel(selCR) ;
  }

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CRichEditCtrl の使用

ダイアログでCRichEditCtrlを使用する場合,InitInstanceなど,ダイアログ表示前にAfxInitRichEdit を呼び出す必要あり(これがないとダイアログが表示されない)
http://msdn.microsoft.com/ja-jp/library/76a787xf(VS.80).aspx
BOOL CXxxxApp::InitInstance()
{
 AfxEnableControlContainer();
 AfxInitRichEdit() ;
 …
 }

VC7 以降は AfxInitRichEdit2
http://msdn.microsoft.com/ja-jp/library/tt1cfb9f(v=VS.80).aspx

WinCtrl4.cpp より
BOOL PASCAL AfxInitRichEdit()
{
  _AFX_RICHEDIT_STATE* pState = _afxRichEditState;
  if (pState->m_hInstRichEdit == NULL)
  pState->m_hInstRichEdit = AfxCtxLoadLibraryW(L”RICHED32.DLL“);
  return pState->m_hInstRichEdit != NULL;
  }
BOOL PASCAL AfxInitRichEdit2()
{
  _AFX_RICHEDIT_STATE* pState = _afxRichEditState;
  if (pState->m_hInstRichEdit2 == NULL)
  pState->m_hInstRichEdit2 = AfxCtxLoadLibraryW(L”RICHED20.DLL“);
  return pState->m_hInstRichEdit2 != NULL;
  }
 
RC 内のコントロールのクラス名 RichEdit20A , RichEdit20W
http://support.microsoft.com/kb/261171
 
VC6 UNICODE exe で,CRichEditCtrl から DDX で文字列を取得すると正しく取れない.
例えば”㎡㎥m” が “㎡?m” になってしまう.
 RC のクラス名を “RICHEDIT” から “RichEdit20W” に変更して正しく取れる様になった.
CRichEditCtrl の使い方  RichEdit20W
 ”RichEdit20A” では,変わらず.
CRichEditCtrl の使い方  RichEdit20A
 
選択項目の変更の通知にはEN_SEL_CHANGEなど
これを使用する場合,OnInitDialogなどで,以下の様な呼び出しでの設定が必要.
 long       em = m_CtrlRichEdit.GetEventMask() ;
 m_CtrlRichEdit.SetEventMask(em|ENM_SELCHANGE) ;
 http://msdn.microsoft.com/ja-jp/library/bb774366.aspx
 
以下の様な方法で,FaceNameを使用可能
 CHARFORMAT  cf ;
 ::ZeroMemory(&cf,sizeof(CHARFORMAT)) ;
 cf.cbSize = sizeof(CHARFORMAT) ;
 m_CtrlRichEdit.GetSelectionCharFormat(cf) ;
 …  = cf.szFaceName ;

保存
 http://msdn.microsoft.com/ja-jp/library/b0k0ywek(v=VS.80).aspx
 

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.