Iwao Dev

気付いたことをメモしています.

この画面は、簡易表示です

MFC

HICON -> DIB

i_DIB	GetIcon_DIB	(LPCTSTR filePath,const long size=300)
{
    i_DIB	dib ;
    HICON	hIcon  = ::DImageS_GetIcon(filePath) ;
    if (hIcon != NULL)	{
        MemoryDC	memDC ;
        memDC.Init(CSize(size,size),32) ;
        CDC*		mem_dc = memDC.GetMemoryDC() ;
        mem_dc->FillSolidRect(CRect(0,0,size,size),RGB(240,240,255)) ;
        ::Icon_Draw(mem_dc->GetSafeHdc(),CRect(10,10,size-10,size-10),hIcon,TRUE,TRUE) ;
        dib = ::ToDIB(memDC) ;
        memDC.Term() ;
        ::DestroyIcon(hIcon) ;
        }
    return	dib ;
    }
この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


CFileStatus でアサート

ファイルの作成日時が正しくない?と CFileStatus でうまく動作しない.


このファイルは,プログラミング Windows 第5版の CD を Mac でコピーしたもの.
このファイルを CFile::GetStatus とすると,アサートなど.
VC 8 の場合,ATLTime.inl CTime コンストラクタの 200 行目付近で
  if(m_time == -1)
  {
    AtlThrow(E_INVALIDARG);
    }


—————————
TsHBMP
—————————
パラメータが間違っています。
—————————
OK
—————————


CFileStatus を使わずに,stat を使用する様に書換えてある程度は動作する様になった.
VC 14 では,stat がエラーで帰ってくる.この対応方法は不明.
CFileStatus を使用している所はかなりあるため,すべてに対応するにはしばらくかかる.
今回は Shell Extension でダウンしたため,その部分のみ対応.

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ

  • Categories:

高 DPI – 2

CMetaFileDC::CreateEnhanced の lpBounds を指定していたが,うまくなかった様で NULL に.
また,これとは異なるが再生デバイスが異なる場合うまくなかったので,
 ENHMETAHEADER の rclFrame ではなく rclBounds に変更.


何を参考にしたのか不明だが,幅を求めるのに TEXTMETRIC だけを使用していた.幾つかあり.
CComboBox::SetDroppedWidth
CListBox::SetHorizontalExtent
CDC::GetTextExtent


高 DPI – 1
高 DPI – 3

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


error LNK2005 LNK2001

プロジェクト生成時に「MFC を使用しない」としたコンソール AP で Afx.h をインクルードした場合


リンク中…
nafxcwd.lib(afxmem.obj) : error LNK2005: “void * __cdecl operator new(unsigned int)” (??2@YAPAXI@Z) はすでに LIBCD.lib(new.obj) で定義されています
nafxcwd.lib(afxmem.obj) : error LNK2005: “void __cdecl operator delete(void *)” (??3@YAXPAX@Z) はすでに LIBCD.lib(dbgdel.obj) で定義されています

nafxcwd.lib(thrdcore.obj) : error LNK2001: 外部シンボル “__endthreadex” は未解決です
nafxcwd.lib(thrdcore.obj) : error LNK2001: 外部シンボル “__beginthreadex” は未解決です


プロジェクトの設定で「共有 DLL で MFC を使う」などに変更.

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


tstring Unit::ToName の呼び出し後エラー

もともと CString Unit::ToName(…) だった関数の戻り値を tstring に変更した.
利用している所の多くは,コンパイルエラーとなり Unit::ToName(…).c_str() と修正したが...
次の様な可変引数の修正が漏れていた.
CString unitStr ; unitStr.Format(_T(“%d_%s”),…,Unit::ToName(…)) ;

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


VC 8 で _ATL_VER が定義される?

先日書いたコードを MFC ダイアログベースの AP で利用してみると,CRegKey の未定義エラー.
コードは,次の様に「_ATL_VER が定義されていれば…」としている.
  #ifdef _ATL_VER
     CRegKey reg ;
     …
  #endif


—— ビルド開始: プロジェクト: SmpMG, 構成: Debug Win32 ——
コンパイルしています…
SmpMGDlg.cpp
…\i_RegGet.hxx(36) : error C2065: ‘CRegKey’ : 定義されていない識別子です。
…\i_RegGet.hxx(36) : error C2146: 構文エラー : ‘;’ が、識別子 ‘reg’ の前に必要です。
…\i_RegGet.hxx(36) : error C2065: ‘reg’ : 定義されていない識別子です。
…\i_RegGet.hxx(37) : error C2228: ‘.Open’ の左側はクラス、構造体、共用体でなければなりません
…\i_RegGet.hxx(39) : error C2228: ‘.QueryDWORDValue’ の左側はクラス、構造体、共用体でなければなりません
SmpMG – エラー 5、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========


VC 6 や,VC 8 のコンソール AP としての利用はうまくいっている.
自分で書いた部分では,_ATL_VER が定義される様なインクルードは追加してない.
_ATL_VER は (VS8)\VC\atlmfc\include\AtlDef.h にある.


StdAfx.h でインクルードしているものを順に追いかけていくと,
AfxDisp.h 内で Atlナントカ.h がインクルードされている.
同様の部分の VC 6 の方では Atl~.h はなさそう.


どの様にするのがベターなのかわからないが,AtlBase.h をインクルードする様にした.
  #ifdef _ATL_VER
  #include <AtlBase.h>
  #endif

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ

  • Categories:

‘新しいテキスト ドキュメント.txt’ …

ちょっと変な状態に陥ったのでメモ.


\\DevS\Documents\MICS\Plan\MICSDat\Test_2015 01-03\9LM-2U-J6TRi-2S7M.001\
\\DevS\Documents\MICS\Plan\MICSDat\Test_2014_12\ などでは
[Window Title]
ファイルを作成できません
[Content]
ファイル ‘新しいテキスト ドキュメント.txt’ を作成できません。
開かれている共有ファイルが多すぎます。
[OK]


\\DevS\Documents\MICS\Plan\MICSDat\ だと戻ってこない(エクスプローラが応答なしになる)
\\DevS\Documents\MICS\Plan\ などでは正しく生成できる.


ログオフ時,\\DevS\Documents\MICS\Plan\MICSDat\新しいテキスト ドキュメント.txt ができていた.
再ログオン後,直後はできなかったがしばらくすると可能となった.


現象はどーってことない(再起動すれば直る)が,
問題は,MFC で作成した普通の AP でドキュメントが消失したこと.
その AP は,自動的に %Temp% にバックアップを保持するので完全に失ったわけではないが,
標準の MFC のシリアライズ動作ではうまくないのか?

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


コンソール AP でレジストリ読み取り

コンソール AP で,レジストリを読み取るために以下の様な関数を用意した.


  int Reg_GetInt (HKEY hKey,LPCTSTR subKey,LPCTSTR ent,const int defValue=0)
  {
     DWORD value = defValue ;
  #ifdef _ATL_VER
     {
       CRegKey reg ;
       reg.Open(hKey,subKey) ;
     #if (_ATL_VER >= 0x700)
       reg.QueryDWORDValue(ent,value) ;
     #else
       reg.QueryValue(value,ent) ;
     #endif
       }
  #else
     {
       HKEY hSecKey = NULL ;
       LONG openStatus = ::RegOpenKeyEx(hKey,subKey,0,KEY_READ,&hSecKey) ;
       if (hSecKey == NULL) { return value ; }
       DWORD type = REG_NONE ;
       DWORD count = sizeof(DWORD) ;
       LONG queryStatus = ::RegQueryValueEx(hSecKey,ent,NULL,&type,(LPBYTE)&value,&count) ;
       ::RegCloseKey(hSecKey) ;
       }
  #endif
     return int(value) ;
     }
*::Reg~ などのエラーチェックは省いている.
呼出すのはこんな感じ.
  int value = ::Reg_GetInt(HKEY_CURRENT_USER,_T(“Software\\Iwao\\Test\\RegAcc”),_T(“T_RegKey_DW”)) ;


CWinApp::GetProfileInt などが使えないかとやってみたが,…
1. AfxGetApp() を呼びだしても,NULL で戻ってくる.
  次の様に領域を確保.
    CWinApp theApp;
2. SetRegistryKey(key) が直接呼びたせないので,
  class C_SRK_WinApp : public CWinApp {
  public:
       void SetRegKey (LPCTSTR key) { SetRegistryKey(key) ; }
     } ;
  変数の確保は次の様に変更.
    C_SRK_WinApp theApp ;
3. SetRegistryKey の中で ASSERT(m_pszAppName != NULL)
  以下を追加して,CWinApp を初期化.
     AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0) ;
4. これで CWinApp::GetProfileInt は利用できるようになるが,CWinApp::m_pszProfileName が邪魔.
   C_SRK_WinApp* app = (C_SRK_WinApp*)AfxGetApp() ;
   int val = app->GetProfileInt(_T(“Test\\RegAcc”),_T(“T_RegKey_DW”),0) ;
  HKCU\Software\Iwao\(m_pszProfileName)\Test\RegAcc となってしまう.
5. m_pszProfileName を _T(“”) とすることにより,意図した値を取得できる様にはなった.
   C_SRK_WinApp* app = (C_SRK_WinApp*)AfxGetApp() ;
   if (app != NULL) {
     AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0) ;
     app->SetRegKey(_T(“Iwao”)) ;
     free((void*)app->m_pszProfileName) ;
     app->m_pszProfileName = _tcsdup(_T(“”)) ;
     int val = app->GetProfileInt(_T(“Test\\RegAcc”),_T(“T_RegKey_DW”),0) ;
     }


コンソール AP で CWinApp::GetProfileInt などを使うことは,やめ.

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


COleDataSource を利用した Drag

以前 DoDragDrop で少し調べたが,その時は途中になっていた.
その時の内容で,例えば CListBox に表示されてるファイルリストのすべてを,CListBox の外側でドラッグするすることはできる.
  void CDragLBDlg::OnLButtonDown(UINT nFlags, CPoint point)
  {
    CStringArray sa ;
    ::ToStringArray(FileNames,&sa) ;
    ::StringArrayToDoDragFiles(sa) ;
    }


CListCtrl であれば,OnBegindragXxxx が利用できるので,
  void CDragLVDlg::OnBegindragListFiles(NMHDR* pNMHDR, LRESULT* pResult)
  {
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    {
      CStringArray sa ;
      for (int index=0 ; index<m_ListFiles.GetItemCount() ; index++) {
        if (m_ListFiles.GetItemState(index,LVIS_SELECTED) == LVIS_SELECTED) {
          tstring str = FileNames[index] ;
          sa.Add(str.c_str()) ;
          }
        }
      if (sa.GetSize() > 0) {
        ::StringArrayToDoDragFiles(sa) ;
        }
      }
    *pResult = 0;
    }


今回やりたかったのは,CListBox の項目のドラッグ.
ドラッグ部分は CListCtrl とほぼ同様となると思われるが,ドラッグ開始のタイミングが取れない.
CDragListBox と開始時の動きは似ているが,MFC のコードを見るとちょっと難しそう.
いろいろと検索すると,CListBox のサブクラス化で対応するみたいとわかったが,手順が...
動的なサブクラス化と言うらしい.
Inside Visual C++ には,囲み記事に CNonNumericEdit がある.
利用する手順はわかるが,作成する手順がわからない
今も利用はしている CView からの VXxxxView ファミリがあるが,10 年以上前で手順は覚えてない.


いろいろ探して「MFC クラスウィザード」を利用することがわかった.
今まで,よく見ていたダイアログなのに...

後は,WM_LBUTTONDOWN を処理する様にして,
  void CMyListBox::OnLButtonDown(UINT nFlags, CPoint point)
  {
    CListBox::OnLButtonDown(nFlags, point);
    int sel = GetCurSel() ;
    if (sel == LB_ERR) { return ; }
    CString str ;
    GetText(sel,str) ;
    CStringArray sa ;
    sa.Add(str) ;
    ::StringArrayToDoDragFiles(sa) ;
    }
ダイアログに追加したリスボックスで,これを利用する様にダイアログのヘッダを修正.


MSDN CTRLTEST サンプル
テクニカル ノート 14
標準コントロールからのコントロールの派生
[MSVC] MFCを使用しての動的サブクラス化
Create Client Windows, Drag and Drop Between Listboxes


2014/08/11 追記
COleDataSource を利用して,他の AP に CF_HDROP で渡そうとすると,
—————————
Microsoft Visual C++ Debug Library
—————————
Debug Assertion Failed!
Program: …Documents\Visual Studio 2010\Projects\TestVC10\Debug\T_SC.exe
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\cmdtarg.cpp
Line: 43
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)
—————————

COleDataSource の使い方が間違っていた.
開放する時に delete ではうまくない.
データ オブジェクトとデータ ソース : 作成と破棄

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ


モードレスダイアログの動作が,…

VC 7 以降,MDI AP のモードレスダイアログが独立して動作してしまう現象があった.
その AP は,VC 4 の頃作成したもので CMainFrame::OnCreate 内でモードレスダイアログを作成している.
VC 6 までは特に問題なかったが,VC 7 以降タスクバーにアイコンが 2 つ存在する状態になってしまっていた.
過去に何度か対応方法を調べたが,わからずそのままとなっていた.


今日別の事を調べていて,「モードレスダイアログで親子にならなくする」方法が目に留まった.
CDialog::Create で,デフォルトの NULL ではなく,GetDesktopWindow() を与えるというもの.
VC 7 AP のダイアログの情報を,Spy++ で見ると,親ウィンドウが (なし) になっている.
今度はデバッガで,Create の付近を追いかけると AfxGetMainWnd() で NULL がかえっている.
ThrdCore.cpp より
CWnd* CWinThread::GetMainWnd()
{
  if (m_pActiveWnd != NULL)
    return m_pActiveWnd;
  if (m_pMainWnd != NULL)
    return m_pMainWnd;
  return CWnd::GetActiveWindow();
}


CXxxApp::InitInstance で以下の部分を修正.
  CMainFrame* pMainFrame = new CMainFrame;
  m_pMainWnd = pMainFrame;   // ここを追加
  if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
    return FALSE;
  m_pMainWnd = pMainFrame;

この投稿は役に立ちましたか? 役に立った 役に立たなかった 0 人中 0 人がこの 投稿 は役に立ったと言っています。

  にほんブログ村 IT技術ブログへ



    top

    %d人のブロガーが「いいね」をつけました。