BDoc ファミリ
コンパイルで以下の様なエラーになった場合
c:\…\DocIB.cxx(77) : error C2065: ‘BDocCSV_D’ : 定義されていない識別子です。
c:\…\DocIB.cxx(77) : error C2146: 構文エラー : ‘;’ が、識別子 ‘bdcsv’ の前に必要です。
c:\…\DocIB.cxx(77) : error C2065: ‘bdcsv’ : 定義されていない識別子です。
c:\…\DocIB.cxx(78) : error C2228: ‘.Read’ : 左側がクラス、構造体、共用体ではありません。
c:\…\DocIB.cxx(79) : error C2228: ‘.BDoc_Draw’ : 左側がクラス、構造体、共用体ではありません。
c:\…\DocIB.cxx(79) : error C2653: ‘BDoc_Draw’ : 識別子がクラス名でも名前空間名でもありません。
DocIB.cxx のインクルードする場所をもう少し前にすることによりエラーはなくなるが,…
実行時,いろいろな所でダウンする(表面化しないこともあり).
BDoc_Draw と BDocCSV_D の定義の不整合が原因.
BDoc ファミリや,AccessItemND を見直さなければならないがちょっと時間が取れない.
ひとまず,App.h に BDoc_D.hxx をインクルードすることにより対応する.
#include “MetaFile.hxx”
#include “MemoryDC.hxx”
#include “BDoc_D_.hxx”
CFont::CreatePointFont でアサート
—————————
Microsoft Visual C++ Debug Library
—————————
Debug Assertion Failed!
Program: C:\WINDOWS\explorer.exe
File: wingdix.cpp
Line: 269
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)
—————————
ここ 1 年位のコードで何個かあったので,…
呼び元で与えられた pDC が CMetaFileDC の場合,m_hAttribDC が NULL となるため.
コードを書いた段階では画面やプリンタだったが,今回 Text → EMF で表面化した.
修正は以下の様な感じ.
// font.CreatePointFont(120,faceName,pDC) ;
if (pDC->m_hAttribDC == NULL) { font.CreatePointFont(120,faceName,NULL) ; }
else { font.CreatePointFont(120,faceName,pDC) ; }
CCheckListBox の使い方
Shell Extension InfoTip の追加
Shell Extension の作成 InfoTip
1.プロジェクトの作成
MFC App Wizard(dll)
「スタティックライブラリを使用した DLL」を選択
「オートメーション」のサポート
2.クラスファクトリの作成
Class Wizard で,クラスの新規作成
基本クラスは CCmdTarget
「タイプ ID で作成」
3.ヘッダ部に INTERFACE_PART の追加
BEGIN_INTERFACE_PART(QueryInfoT,IQueryInfo)
STDMETHOD (GetInfoFlags) (DWORD* pdwFlags) ;
STDMETHOD (GetInfoTip ) (DWORD dwFlags,LPWSTR* ppwszTip) ;
END_INTERFACE_PART (QueryInfoT)
…
BEGIN_INTERFACE_PART(PersistFile,IPersistFile)
…
4.必要な変数を追加
InfoTip の場合,FileName など
5.ソースに INTERFACE_MAP の追加
BEGIN_INTERFACE_MAP(CI_ShellExt,CCmdTarget)
INTERFACE_PART (CI_ShellExt,IID_IQueryInfo,QueryInfoT)
INTERFACE_PART (CI_ShellExt,IID_IPersistFile,PersistFile)
END_INTERFACE_MAP ()
6.CI_ShellExt::XQueryInfoT::~ の実装
幾つかはある程度決まったコードになる.
CI_ShellExt::XQueryInfoT::GetInfoTipは,ppwszTipに表示する文字列を返す.
METHOD_PROLOGUE pThisでCCmdTargetの派生クラスにアクセス可能になる.
レジストリへの登録
[HKEY_CURRENT_USER\Software\Classes\CLSID\{56D044C5-9F47-4CD3-B130-9E52BE7460F3}]
@=”I.ShellExt”
[HKEY_CURRENT_USER\Software\Classes\CLSID\{56D044C5-9F47-4CD3-B130-9E52BE7460F3}\InProcServer32]
@=”C:\\Documents and Settings\\All Users\\Documents\\VC_TEST\\IShlExt\\Release\\I_Shl_E.dll”
“ThreadingModel”=”Apartment”
[HKEY_CURRENT_USER\Software\Classes\CLSID\{56D044C5-9F47-4CD3-B130-9E52BE7460F3}\ProgID]
@=”I.ShellExt”
拡張子の登録例
[HKEY_CURRENT_USER\Software\Classes\.Test_ShellExt\ShellEx\{00021500-0000-0000-C000-000000000046}]
@=”{56D044C5-9F47-4CD3-B130-9E52BE7460F3}”
{56D044C5-9F47-4CD3-B130-9E52BE7460F3} の部分は,ソースの IMPLEMENT_OLECREATE の前の行のコメントより
今回使用したコードは,IShlExt.zip
参考にしたのは,
Debugging with the Shell
MSDN Magazine 2000/04 新しいinfotip,アイコンオーバーレイ,シェルエクステンション
Windows 2000 UI Innovations: Enhance Your User’s Experience with New Infotip and Icon Overlay Shell Extensions
MSDN Magazine 2000/07 ハイパーテキストテンプレートファイルのカスタマイズによるエクスプローラの表示の拡張
Windows 95 ユーザーインターフェイス プログラミング
ExtractImage を実装してエラーになった場合
I_ShlExt.obj:error LNK2001:外部シンボル “_IID_IExtractImage” は未解決です
#include <initguid.h> を I_ShlExt.cpp の StdAfx.h の次に追加.
XML の読込テスト – 4
全ては表現できてないが,msxml.dll により読込んだデータの関連はこんな感じか?
IXMLDOMDocument | ||||||
documentElement | ——– | IXMLDOMElement | ||||
attributes | ——– | IXMLDOMNamedNodeMap | ||||
length | ||||||
item 0 | ——– | IXMLDOMAttribute | ||||
: | ||||||
item n-1 | name | |||||
value | ||||||
childNodes | ——– | IXMLDOMNodeList | ||||
length | ||||||
item 0 | ——– | IXMLDOMElement | ||||
: | ||||||
: | ||||||
item n-1 | ——– | IXMLDOMNode | ||||
text | ||||||
nodeName | ||||||
tagName | ||||||
XML の読込テスト – 3
BOOL ReadElement( MSXML::IXMLDOMElementPtr pElement, long indent ) { CString tab = _T("\t\t\t\t\t\t\t\t\t\t\t\t\t") ; CString lsp = tab.Left(indent) ; if (pElement == NULL) { return FALSE ; } MSXML::IXMLDOMNodeListPtr pNode = pElement->GetchildNodes() ; { CString node = LPCTSTR(pElement->GetnodeName()) ; CString tagN = LPCTSTR(pElement->GettagName()) ; CString text ; // if (pNode->Getlength() == 0) { text = LPCTSTR(pElement->Gettext()) ; // } MSXML::IXMLDOMNamedNodeMapPtr aMap = pElement->Getattributes() ; CString str ; if (aMap != NULL) { str = ::ToString(aMap->Getlength()) ; for (int aIndex=0 ; aIndex<aMap->Getlength() ; aIndex++) { MSXML::IXMLDOMAttributePtr attr = aMap->Getitem(aIndex) ; if (attr == NULL) { continue ; } str += CString(_T("\t")) + LPCTSTR(attr->Getname()) ; str += CString(_T(" ")) + ::ToStringTC(LPCWSTR(attr->Getvalue().bstrVal)) ; } } cout << LPCTSTR(lsp) << LPCTSTR(node) << _T("\t") << LPCTSTR(text) << _T("\t") << LPCTSTR(str) << endl ; for (int index=0 ; index<pNode->Getlength() ; index++) { MSXML::IXMLDOMElementPtr child = pNode->Getitem(index) ; ReadElement(child,indent+1) ; } } return TRUE ; }
attr->value が,VARIANT で,VT_BSTR
これを LPCTSTR とすることは出来ず,::ToStringTC をしている.
::ToStringTC は引数とコンパイルオプションにより char* ⇔ wchar* が可能
今回の場合,内部では ::WideCharToMultiByte で変換している.
要素の内容の取得はこんな感じか?
// text = LPCTSTR(pElement->Gettext()) ; if (pNode->Getlength() > 0) { MSXML::IXMLDOMNodePtr pText = pNode->Getitem(0) ; if (pText != NULL) { text = LPCTSTR(pText->text) ; } }
XML の読込テスト – 2
要素へのアクセスはこんな感じと思われるが,Gettext の使い方がよくわからない.
BOOL ReadElement(MSXML::IXMLDOMElementPtr pElement,long indent)
{
CString tab = _T(“\t\t\t\t\t\t\t\t\t\t\t\t\t”) ;
CString lsp = tab.Left(indent) ;
if (pElement == NULL) { return FALSE ; }
MSXML::IXMLDOMNodeListPtr pNode = pElement->GetchildNodes() ;
{
CString node = LPCTSTR(pElement->GetnodeName()) ;
CString tagN = LPCTSTR(pElement->GettagName()) ;
CString text ;
// if (pNode->Getlength() == 0) {
text = LPCTSTR(pElement->Gettext()) ;
// }
cout << LPCTSTR(lsp) << LPCTSTR(node) << _T(“\t”) << LPCTSTR(text) << endl ;
for (int index=0 ; index<pNode->Getlength() ; index++) {
MSXML::IXMLDOMElementPtr child = pNode->Getitem(index) ;
ReadElement(child,indent+1) ;
}
}
return TRUE ;
}
BOOL TestXML (void)
{
…
if (pDoc->load(LPCTSTR(loadFile)) == VARIANT_TRUE) {
{
MSXML::IXMLDOMElementPtr root = pDoc->documentElement ;
ReadElement(root,0) ;
}
}
…
}
XML の読込テスト
// L_xml_2.cpp : コンソール アプリケーション用のエントリ ポイントの定義
//
#include “StdAfx.h”
#include “L_xml_2.h”
#import <msxml.dll> named_guids
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL TestXML (void)
{
HRESULT hr = ::CoInitialize(NULL) ;
if (FAILED(hr)) { return FALSE ; }
{
MSXML::IXMLDOMDocumentPtr pDoc = NULL ;
hr = pDoc.CreateInstance(MSXML::CLSID_DOMDocument) ;
if (FAILED(hr)) { return FALSE ; }
CString loadFile = _T(“test.xml”) ;
{
if (pDoc->load(LPCTSTR(loadFile)) == VARIANT_TRUE) {
printf(“%s\r\n”,(LPCSTR)pDoc->xml) ;
{
MSXML::IXMLDOMElementPtr root = pDoc->documentElement ;
CString tagN = LPCTSTR(root->tagName) ;
CString text = LPCTSTR(root->text) ;
printf(“<%s>%s\r\n”,tagN,text) ;
MSXML::IXMLDOMNodeListPtr nodeL = root->childNodes ;
for (int index=0 ; index<nodeL->Getlength() ; index++) {
MSXML::IXMLDOMElementPtr child = nodeL->Getitem(index) ;
CString tagN = LPCTSTR(child->tagName) ;
CString text = LPCTSTR(child->text) ;
printf(“<%s>%s\r\n”,tagN,text) ;
}
}
}
else {
printf(_T(“error … %s\r\n%s\r\n”),loadFile,(LPCSTR)pDoc->parseError->Getreason()) ;
}
}
}
::CoUninitialize() ;
return TRUE ;
}
/////////////////////////////////////////////////////////////////////////////
// 唯一のアプリケーション オブジェクト
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// MFC の初期化および初期化失敗時のエラーの出力
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 必要に応じてエラー コードを変更してください。
cerr << _T(“Fatal Error: MFC initialization failed”) << endl;
nRetCode = 1;
}
else
{
/*
// TODO: この位置にアプリケーションの動作を記述してください。
CString strHello;
strHello.LoadString(IDS_HELLO);
cout << (LPCTSTR)strHello << endl;
*/
TestXML() ;
}
return nRetCode;
}
勘違いをしていたので, ±×÷
UNICODE で,±×÷ はそれぞれ,U+00B1 , U+00D7 , U+00F7 になる.
以下は,よく参考にさせてもらっている所
文字コード(日本語漢字コード表)