ホーム » MFC (ページ 8)

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

2024年4月
 123456
78910111213
14151617181920
21222324252627
282930  

カテゴリー

アーカイブ

ブログ統計情報

  • 80,353 アクセス



MFC Static → DLL

MFC を「スタティック ライブラリ」から「共有 DLL」に変更した時,以下のエラーになることがある.
—— ビルド開始: プロジェクト: Project , 構成: Release Win32 ——
コンパイルしています…
StdAfx.cpp
C:Program FilesMicrosoft Visual Studio 8VCatlmfcincludeafx.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]
Project – エラー 1、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
*.vcproj をエディタで開き,"$(NoInherit)" を削除


2010/04/21 追記
—— ビルド開始: プロジェクト: Project , 構成: Release Win32 ——
StdAfx.cpp
C:Program Files (x86)Microsoft Visual Studio 10.0VCatlmfcincludeafxver_.h(81): fatal error C1189: #error : Please use the /MD switch for _AFXDLL builds
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
プロジェクトの「プロパティ」-「構成プロパティ」-「C/C++」-「コード生成」-「ランタイムライブラリ」
マルチスレッド (/MT) → マルチスレッド DLL (/MD)


2021/06
https://dev.mish.work/wordpress/2021/01/23/vc-12-lnk1104-vc14-2-lnk2019/
https://dev.mish.work/wordpress/2021/04/01/change-mfc-static-error/

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

FileVer.* を使用した CAboutDlg

CAboutDlg を表示する時に IDC_STATIC による固定的な情報を使用するのではなく,バージョンリソースを使用する

  1. IDD_ABOUTBOX の IDC_STATIC を IDC_FV_DESCRIPTION_VERSION と IDC_FV_LEGAL_COPYRIGHT に変更.
  2. IDC_FV_XXX で始まる使用できるものは,FileVer.cxx を参照.個別の12個と組合せの1個を用意 . 
  3. CAboutDlg::OnInitDialog() で,SetAboutFileVer(this) を呼び出す. 
  4. リンク時に Version.lib がなければ追加.

http://cid-535f5973454c1292.skydrive.live.com/embedicon.aspx/.Public/MFC/FileVer.zip
FileVer.zip


2022/07/28
::GetFileVersionInfo
FVersion.hxx

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

Outlook で配信不能になる

2018/04/06 新しく書き直し


受信者をコードで指定していると Outlook で配信不能になる(OE では問題ない).

配信不能 : Subject
システム管理者
送信日時 2010/02/19(金) 21:20
宛先   **********


このメールは、受信者全員または一部に届きませんでした。
件名: Subject
送信日時: 2010/02/19 21:20
以下の受信者にメールを配信できません: 
‘user@*******.com’ 2010/02/19 21:20
この受信者へ配信できる電子メール アカウントはありません。


受信者のメールアドレスを設定する時,_T("smtp:") を付加する

// DOCMAPI.CPP  CDocument::OnFileSendMail
//*******************************************************************************
// 関数名 :ファイルの送信
// 作成日 :’06/06/23
//*******************************************************************************

BOOL SendMail::Send (void) const
{
  if (!IsSupport()) { return FALSE ; }
  CheckSizeAlert() ;
  // MultiByte の必要があるようなので,UNICODE の時のバッファをここに登録する
  LateDelete ld ;
  // 添付ファイルの準備
   int fileCount = 0 ;
   CArray<MapiFileDesc,MapiFileDesc> fileDescA ;
   int index = 0 ;
   for (index=0 ; index<PathNames.GetSize() ; index++) {
      CString pathName = PathNames[index] ;
      if (::FileIsNothing (pathName)) { continue ; }
      if (::FileIsDirectory(pathName)) { continue ; }
      MapiFileDesc fileDesc ;
      memset(&fileDesc,0,sizeof(MapiFileDesc)) ;
      fileDesc.nPosition = (ULONG)-1 ;
      #ifdef _UNICODE
        fileDesc.lpszPathName = SendMail__ChangeMultiByte(PathNames[index],&ld) ;
        fileDesc.lpszFileName = SendMail__ChangeMultiByte(FileNames[index],&ld) ;
      #else
        fileDesc.lpszPathName = LPSTR(LPCTSTR(PathNames[index])) ;
        fileDesc.lpszFileName = LPSTR(LPCTSTR(FileNames[index])) ;
      #endif
      fileDescA.Add(fileDesc) ;
      fileCount++ ;
      }
    // 受信者の準備
    int recipCount = 0 ;
    CArray<MapiRecipDesc,MapiRecipDesc> recipDescA ;
    CStringArray recipName ;
    CStringArray recipAddr ;
    for (index=0 ; index<Recipient.GetSize() ; index++) {
        recipName.SetAtGrow(index,Recipient[index]) ;
        recipAddr.SetAtGrow(index,Recipient[index]) ;
        if (IsAddressAddSMTP()) {
            recipAddr.SetAtGrow(index,_T("smtp:")+Recipient[index]) ;
            }
        }
    for (index=0 ; index<Recipient.GetSize() ; index++) {
      MapiRecipDesc recipDesc ;
      memset(&recipDesc,0,sizeof(MapiRecipDesc)) ;
      recipDesc.ulRecipClass = MAPI_TO ;
      #ifdef _UNICODE
        recipDesc.lpszName = SendMail__ChangeMultiByte(recipName[index],&ld) ;
        recipDesc.lpszAddress = SendMail__ChangeMultiByte(recipAddr[index],&ld) ;
      #else
        recipDesc.lpszName = (LPSTR)((LPCTSTR)(recipName[index])) ;
        recipDesc.lpszAddress = (LPSTR)((LPCTSTR)(recipAddr[index])) ;
      #endif
      recipDescA.Add(recipDesc) ;
      recipCount++ ;
      }
    MapiMessage message ;
    memset(&message,0,sizeof(message)) ;
    message.nFileCount = fileCount ;
    message.lpFiles = fileDescA.GetData() ;
    message.nRecipCount = recipCount ;
    message.lpRecips = recipDescA.GetData() ;
    #ifdef _UNICODE
       message.lpszSubject = SendMail__ChangeMultiByte(GetSubject(), &ld) ;
       message.lpszNoteText = SendMail__ChangeMultiByte(GetNoteText(), &ld) ;
    #else
       message.lpszSubject = LPSTR(LPCTSTR(Subject)) ;
       message.lpszNoteText = LPSTR(LPCTSTR(NoteText)) ;
    #endif
    CWnd* mainWnd = AfxGetMainWnd() ;
    #if(_MFC_VER >= 0x0700)
       ULONG_PTR hWnd = (ULONG_PTR)mainWnd->GetSafeHwnd() ;
    #else
       ULONG hWnd = (ULONG) mainWnd->GetSafeHwnd() ;
    #endif
    int nError = pSendMail(0, hWnd,&message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
    if (nError != SUCCESS_SUCCESS &&
        nError != MAPI_USER_ABORT &&
        nError != MAPI_E_LOGIN_FAILURE) {
        AfxMessageBox(AFX_IDP_FAILED_MAPI_SEND) ;
        Copy() ;
        }
     return TRUE ;
     }

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

クリップボードへのテキストの転送

//  WinMFC.hxx
//*******************************************************************************
// 関数名 :クリップボードへのテキストの転送
// 作成日 :’01/07/13
// 変更日 :’07/12/14 UNICODE テキスト対応
//*******************************************************************************
inline
BOOL SetClipboardText (LPCTSTR text)
{
 CString   str = text ;
 GLOBALHANDLE hGMemText = 0 ;
 {
  hGMemText = ::GlobalAlloc(GHND,(DWORD)(str.GetLength()+1)*sizeof(TCHAR)) ;
  LPSTR  lpText = (LPSTR)::GlobalLock(hGMemText) ;
  memmove(lpText,str,str.GetLength()*sizeof(TCHAR)) ;
  ::GlobalUnlock(hGMemText) ;
  }
 {
  BOOL ret = ::OpenClipboard(NULL) ;
  if (ret == FALSE) {
   ::GlobalFree(hGMemText) ;
   ::MessageBeep(0) ;
   ::MessageBox(NULL,_T("ERROR: Cannot access the Clipboard!"),AfxGetAppName(),MB_OK|MB_ICONEXCLAMATION) ;
   return FALSE ;
   }
  else {
   ::EmptyClipboard() ;
   #ifdef _UNICODE
   ::SetClipboardData(CF_UNICODETEXT, hGMemText) ;
   #else
   ::SetClipboardData(CF_TEXT,   hGMemText) ;
   #endif
   ::CloseClipboard() ;
   }
  }
 return TRUE ;
 }
 
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

利用可能なドライブ名の列挙 GetLogicalDrives

GetLogicalDrives

//*******************************************************************************
// 関数名 :利用可能なドライブ名の列挙
// 作成日 :’10/02/02
//*******************************************************************************
CString GetLogicalDriveName (void)
{
    DWORD drives = ::GetLogicalDrives() ;
    long defaultDrive = -1 ;
    CString driveName ;
    for (int index=0 ; index<30 ; index++) {
        if (drives & (1<<index)) {
            driveName += 'A'+index ;
            }
        }
    return driveName ;
    }
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

Disable にされたラジオボタンでアサート

Disable にされたラジオボタンで,そのボタンが選択状態(値がそのボタン)の時,DDX を使用していると Debug 版でアサートされる.
Release 版では,うまく動作する様に見える場合もあるが,他の値に変更されない場合もある.
UpdateData(FALSE) のみを使用している場合は OK.
//*******************************************************************************
// 関数名 :指定されたコントロールの無効化
// 作成日 :’09/11/11
// 変更日 :’10/01/26 ラジオボタンで選択されている時,アサートされたバグの対応
//*******************************************************************************
inline
BOOL MDlgMod::DisableControlID (CWnd* wnd,const CUIntArray& disCmmdIDs,const BOOL isDisable)
{
    BOOL isEnable = (isDisable) ? FALSE : TRUE ;
    if (wnd == NULL)   { return FALSE ;  }
    for (INT_PTR index=0 ; index<disCmmdIDs.GetSize() ; index++) {
        UINT id = disCmmdIDs[index] ;
        if (id == 0)  { continue ; }
        CWnd* ctrl = wnd->GetDlgItem(id) ;
        if (ctrl == NULL) { continue ; }
        if (!isEnable) {
            if (_AfxIsRadioButton(ctrl->GetSafeHwnd())) {     // CtlPPG.cpp
                if (Button_GetCheck(ctrl->GetSafeHwnd())) {  // WindowsX.h
                    continue ;
                    }
                }
            }
        ctrl->EnableWindow(isEnable) ;
        }
    return TRUE ;
    }
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

コントロールがラジオボタンかどうかの判断

// CtlPPG.cpp より
BOOL AFXAPI _AfxIsRadioButton(HWND hWnd)
{
    DWORD dwButtonStyle = GetWindowLong(hWnd, GWL_STYLE) & 0x0000000FL;
    return ((dwButtonStyle == BS_RADIOBUTTON) ||
               (dwButtonStyle == BS_AUTORADIOBUTTON));
 }
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

ダイアログにドロップ機能の追加

「ダイアログ プロパティ」-「拡張スタイル」タブ内の「ドラッグアンドドロップを許可」にチェック.
「MFC ClassWizard」の「クラス情報」-「詳細設定オプション」の「メッセージフィルタ」を「ウィンドウ」に.
「メッセージマップ」の「メッセージ」内の WM_DROPFILES を追加.


void C???Dlg::OnDropFiles(HDROP hDropInfo) 
{
    CStringArray dropFiles ;
    ::DropFilesToStringArray(hDropInfo,dropFiles) ;
    ...
    CDialog::OnDropFiles(hDropInfo);
}
//   WinMFC.hxx
//*******************************************************************************
// 関数名 :ドロップされたファイル名の取得
// 作成日 :’07/10/19
//*******************************************************************************
BOOL DropFilesToStringArray (HDROP hDropInfo,CStringArray& strAry)
{
    UINT nFiles = ::DragQueryFile(hDropInfo,(UINT)-1,NULL,0) ;
    CStringArray dropFiles ;
    for (UINT index=0 ; index<nFiles ; index++) {
         UINT len = ::DragQueryFile(hDropInfo,index, NULL,0) ;
              len += 1 ; // 終端の NULL 文字の分を確保
         CString dropFile ;
         ::DragQueryFile(hDropInfo,index,dropFile.GetBuffer(len),len) ;
         dropFile.ReleaseBuffer() ;
         dropFiles.Add(dropFile) ;
         }
    strAry.Copy(dropFiles) ;
    return TRUE ;
    }

2014/06/02 v_tstring DropFilesTo (HDROP hDropInfo) { v_tstring dropFiles ; UINT nFiles = ::DragQueryFile(hDropInfo,(UINT)-1,NULL,0) ; for (UINT index=0 ; index<nFiles ; index++) { UINT len = ::DragQueryFile(hDropInfo,index, NULL,0) ; len += 1 ; // reserve last '\0' tstring dropFile ; dropFile.resize(len,0) ; ::DragQueryFile(hDropInfo,index,&dropFile[0],len) ; dropFiles.push_back(dropFile.c_str()) ; } return dropFiles ; }
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

複数のツールバーを横に並べて作成

//*******************************************************************************
// 関数名 :ツールバーの作成の後処理
// 作成日 :’05/06/16
// 変更日 :’07/04/06
//*******************************************************************************
// MFC\General\DockTool\MainFrm.cpp DockControlBarLeftOf より
BOOL	ToolBar::CreateDocking	(
	CFrameWnd*	frameW,
	CToolBar*	toolBar,
	UINT		idr,
	CString		title,
	UINT		barID,
	CToolBar*	last,
	const	BOOL	canFloat		//	フローティング可能かどうか
	)
{
	toolBar->SetWindowText(title) ;                                            	//  ウィンドウタイトルの設定
//	toolBar->SetBarStyle(toolBar->GetBarStyle()|CBRS_TOOLTIPS|CBRS_FLYBY) ;  	//  ツール チップなどの付加
	toolBar->EnableDocking(CBRS_ALIGN_ANY) ;                                       	//  ドッキング可能に
	Resize(toolBar,idr) ;	//	ツールバーのリサイズ
	{	//	ツールバーの位置を決定する
		static	CToolBar*		LastToolBar = NULL ;			//  前のツールバーの位置
		if (last != NULL)	{	LastToolBar = last ;	}		//  前のツールバーが指定された
		if (LastToolBar == NULL || barID != 0) {
			CControlBar*	pDockBar = frameW->GetControlBar(barID) ;
			if (pDockBar != NULL && canFloat) {
				frameW->DockControlBar(toolBar,barID) ;
				}
			}
		else {
			frameW->RecalcLayout() ;
			CRect		rect ;
			LastToolBar->GetWindowRect(&rect);
			rect.OffsetRect(1,1);
			DWORD		dw = LastToolBar->GetBarStyle();
			UINT		tBarID = 0 ;
			tBarID = (dw&CBRS_ALIGN_TOP)	            	?  AFX_IDW_DOCKBAR_TOP    : tBarID ;
			tBarID = (dw&CBRS_ALIGN_BOTTOM	&& tBarID==0)	?  AFX_IDW_DOCKBAR_BOTTOM : tBarID ;
			tBarID = (dw&CBRS_ALIGN_LEFT	&& tBarID==0)	?  AFX_IDW_DOCKBAR_LEFT   : tBarID ;
			tBarID = (dw&CBRS_ALIGN_RIGHT	&& tBarID==0)	?  AFX_IDW_DOCKBAR_RIGHT  : tBarID ;
			CControlBar*	pDockBar = frameW->GetControlBar(tBarID) ;
			if (pDockBar != NULL && canFloat) {
				frameW->DockControlBar(toolBar,tBarID,&rect) ;
				}
			}
		LastToolBar = toolBar ;				//  次のツールバーの位置を求めるために保存しておく
		}
	return	TRUE ;
	}

http://cid-535f5973454c1292.skydrive.live.com/embedicon.aspx/.Public/MFC/ToolBar.hxx
ToolBar.hxx


ToolBar.hxx

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

CMenu::SetDefaultItem()

CMenu::SetDefaultItem() では,サブメニューに設定できない

CMenu menu ;
CMenu* pPopup = menu.GetSubMenu(0);
pPopup->SetDefaultItem(defaultID) ;

pPopup->TrackPopupMenu(flags,point.x,point.y,AfxGetMainWnd()) ;

上のコードでは,トップレベルのコマンドには可能だが,そのサブメニューには対応できない.
以下の様に順に辿っていく必要がある

//*******************************************************************************
// 関数名 :既定のメニューの設定
// 作成日 :’09/11/12
//*******************************************************************************

inline BOOL MenuMod::SetDefaultItem (CMenu* menu,const UINT defaultID)
{
 if (menu == NULL)   { return FALSE ;  }
 int  menuCount = menu->GetMenuItemCount() ;
 for (int index=menuCount-1 ; 0<=index ; index–) {
  UINT menuItemID = menu->GetMenuItemID(index) ;
  if (ID_SEPARATOR    ==menuItemID)  { continue ; } // SEPARATOR
  if (menuItemID == defaultID) {
   return menu->SetDefaultItem(index,TRUE) ;
   }
  CMenu* subMenu = menu->GetSubMenu(index) ;
  if (subMenu != NULL) {
   MenuMod::SetDefaultItem(subMenu,defaultID) ;
   }
  }
 return FALSE ;
 }

MenuMod.hxx

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

ShellExtension

CXxx::XPersistFile::Load は呼ばれるのに CXxx::XExtractIcon::GetIconLocation が呼ばれない
 
[HKEY_CLASSES_ROOTCLSID{xxxxxxxx-…xxxxxxxxxxxx}InProcServer32]
@="ExtentionDLL.dll"
"ThreadingModel"="Apartment"
 
TheredingModel を指定すれば呼ばれるようになった
 
2008/04/03 16:25
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

Tool Bar のドロップダウンボタン

VC7 exe で,ビジュアルスタイルが有効な時,ツールバーの幅が正しくない
  VC7.1 もNG  VC8 以降では OK
VC6 exe で,リサイズした時ダウン
2009/06/18 10:48

http://cid-535f5973454c1292.skydrive.live.com/self.aspx/.Public/MFC/%e3%83%84%e3%83%bc%e3%83%ab%e3%83%90%e3%83%bc%e3%81%ae%e3%83%89%e3%83%ad%e3%83%83%e3%83%97%e3%83%80%e3%82%a6%e3%83%b3%e3%83%9c%e3%82%bf%e3%83%b3.txt
ツールバーのドロップダウンボタン.txt

2010/09/02 ツールバーにドロップダウンボタン

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

MFC DLL → Static

Open Dialog , Print Preview でのエラー

ダイアログの DDV でメッセージなし(アイコンのみ)

VC7 共有DLL Static DLL に変更した場合

Vista Common Ctrl 6 が有効にならない

Project . Manifest の不備

Neme = …. Project

確認済

Print Preview

DDV

「リソース」-「全般」のプリプロセッサを削除

  _AFXDLL を削除

確認済

LNK2019: 未解決の

_mainCRTStartup で..

「リンカ」-「システム」-「サブシステム」が

  設定なしになっている
  ⇒
Windows (/SUBSYSTEM:WINDOWS)

 

 ?

fatal error C1189: #error : Please use the /MD switch for _AFXDLL builds

ソースのプロパティに _AFXDLL が含まれているのでそれを削除

 

 

補足(static 共有に戻した時)

$(NoInherit) を削除する必要もあった

 

VS2010β2 で「C++Runtime Library」を /MD /MT

確認済

2009/06/17 22:46

2009/09/16 10:45 追加

2009/10/21 10:04 追加

2009/11/27 17:20 追加

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

UNICODE と VC6 → VC8

VC6 UNICODE
 wWinMainCRTStartup

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

「プリコンパイル済みヘッダファイル」 $(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.

コンテキストメニューで MK_SHIFT , MK_CONTROL

switch (message) {
      case WM_MOUSEMOVE :    Mouse.Move(Wnd,point) ;  return TRUE ; break ;
      case WM_RBUTTONUP :    return Context (msg) ;                 break ;
      case WM_CONTEXTMENU :  return Context (msg) ;                 break ;
      case WM_COMMAND :      return Command (msg) ;                 break ;
      default :                                                     break ;
      }
//  MK_SHIFT | MK_CONTROL が押されている場合は,WM_RBUTTONUP で処理している
BOOL ????????::Context (const MSG* msg)
{
      WPARAM nFlags = GetMouseFlags (msg) ;   // キーフラグ
//    CPoint point  = GetClientPoint(msg) ;   // カーソル位置
      {
            UINT message = GetMessage(msg) ;  // メッセージ番号
            if (message == WM_RBUTTONUP) {
                  if      (nFlags & MK_CONTROL)       { ; }
                  else if (nFlags & MK_SHIFT)         { ; }
                  else                                { return FALSE ; }
                  }
            else { // WM_CONTEXTMENU の時は,キーの状態は無効
                  nFlags = 0 ;
                  }
            }
//    if (???????->PopupSelect(nFlags,point,TRUE))    { return TRUE ; }
//      ...
      }
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

Windows 7 のタスクバー(進行状況バー)

VS 2010 β2
 
ITaskbarList3* GetITaskbarList3 (void)
{
      ITaskbarList3* pTL3 = NULL ;
      HRESULT   hr  = NULL ;
      hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,IID_ITaskbarList3, (void**)&pTL3) ;
       if (hr == NOERROR) {
            return pTL3 ;
            }
      return NULL ;
      }
 
   if (TL3 != NULL) {
      TL3->SetProgressState(this->GetSafeHwnd(),TBPF_NORMAL) ;
      }
   if (TL3 != NULL) {
      TL3->SetProgressValue(this->GetSafeHwnd(),Counter,100) ;
      }
 
 
Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.