#define MRSM( buf , szto ) \
MyReplaceSymbol( (buf) , "INSERTION", 1 , (szto) )
#define GetSubMenuDirect( hwnd , npos ) GetSubMenu( GetMenu( ( HWND )( hwnd) ) , (npos) )
#define EnableDlgItem( hdlg , id , bEnable ) EnableWindow( GetDlgItem( (HWND)hdlg , (UINT)(id) ) , (BOOL)(bEnable) )
#define FIELDOFFSET( stname , field ) ((DWORD)&((stname *)0 )->field )
#define isnum(c) ( (c) ? strchr( "0123456789", (c) ) : 0 )
inline char *GetWindowTextAlloc( HWND hCombo )
{
int tlen = GetWindowTextLength( hCombo ) ;
char *ret = (char *)malloc( tlen+1 ) ;
GetWindowText( hCombo , ret , tlen+1 ) ;
return ret ;
}
// Editコントロール追加マクロ
#define Edit_ExSetSel( hEdit , lpchrg ) SendMessage( (HWND)(hEdit) , EM_EXSETSEL , 0L , (LPARAM)(lpchrg) )
#define Edit_ExGetSel( hEdit , lpchrg ) SendMessage( (HWND)(hEdit) , EM_EXGETSEL , 0L , (LPARAM)(lpchrg) )
#define Edit_CharFromPos( hEdit , x , y ) ((int)SendMessage( (HWND)(hEdit) , EM_CHARFROMPOS , 0L , MAKELPARAM((x),(y)) ) )
#define Edit_SetFirstVisibleLine( hEdit , ln ) \
Edit_Scroll( (hEdit) , (ln) - Edit_GetFirstVisibleLine( (hEdit) ) , 0 )
#define Edit_LineFromCharEx( hEdit , ichCharPos ) \
( int )SendMessage( (hEdit) , EM_EXLINEFROMCHAR , 0L , (ichCharPos) )
#include <richedit.h>
inline LRESULT Edit_SetTextEx( HWND hEdit , const char *buf )
{ // SETTEXTEX stx = { ST_DEFAULT | ST_KEEPUNDO , CP_ACP } ;
SETTEXTEX stx ; stx.flags = ST_DEFAULT | ST_KEEPUNDO ; stx.codepage = CP_ACP ;
return SendMessage( hEdit , EM_SETTEXTEX , (WPARAM)&stx , (LPARAM)buf ) ;
}
inline LRESULT Edit_GetTextEx
( HWND hEdit , char *buf , DWORD cb )
{ //GETTEXTEX gtx =
//{ cb , GT_USECRLF , CP_ACP , NULL , NULL } ;
GETTEXTEX gtx ;
gtx.cb = cb ; gtx.flags = GT_USECRLF ; gtx.codepage = CP_ACP ;
gtx.lpDefaultChar = NULL ; gtx.lpUsedDefChar = NULL ;
return SendMessage( hEdit , EM_GETTEXTEX , (WPARAM)>x , (LPARAM)buf ) ;
}
LRESULT Edit_GetSelTextEx
( HWND hEdit , char *buf , DWORD cb )
{ // cb は バイトサイズ
LRESULT ret ;
GETTEXTEX gtx =
{ cb , GT_USECRLF | GT_SELECTION , CP_ACP , NULL , NULL } ;
// EM_GETTEXTEX はバグ。
ret = SendMessage( hEdit , EM_GETTEXTEX , (WPARAM)>x , (LPARAM)buf ) ;
{ CHARRANGE Chrg ;
SendMessage( hEdit , EM_EXGETSEL , 0L , (LPARAM)&Chrg ) ;
char *lpch ;
for( lpch = buf ; ( Chrg.cpMin != Chrg.cpMax) && *lpch ; Chrg.cpMin ++ )
if( (IsDBCSLeadByte( *lpch ) || *lpch == '\r') && *(lpch +1) ) lpch += 2 ;
else lpch ++ ;
*lpch = '\0' ;
}
return ret ;
}
inline int Edit_ExGetCurrentLine( HWND hEdit )
{ CHARRANGE Chrg ; SendMessage( hEdit , EM_EXGETSEL , 0L , (LPARAM)&Chrg ) ;
// DO NOT MODIFY "SendMessage" sentence to Edit_ExGetSel Macro ...
return (int)SendMessage( hEdit , EM_EXLINEFROMCHAR , 0L , Chrg.cpMin ) ;
}
inline BOOL Edit_SelIsEmpty( HWND hEdit )
{ CHARRANGE chrg ;
SendMessage( hEdit , EM_EXGETSEL , 0 ,(LPARAM)&chrg ) ;
if( chrg.cpMax - chrg.cpMin ) return FALSE ;
return TRUE ;
}
//-- 2004/Oct/17
#include <commdlg.h>
inline void GetStandardOfn
( OPENFILENAME *pofn , HWND hWnd , char *lpInitdir ,
char *lpFormattedFilter , char *lpszRet , int maxbuf , DWORD dwFlags ,
char *lpTitle )
{
ZeroMemory( pofn , sizeof( OPENFILENAME) ) ;
pofn->lStructSize = sizeof( OPENFILENAME ) ;
pofn->hwndOwner = hWnd ;
pofn->lpstrFilter = lpFormattedFilter ;
pofn->Flags = dwFlags ; // OFN_FILEMUSTEXIST | OFN_HIDEREADONLY ;
pofn->lpstrDefExt = NULL ; // 拡張子を省略して入力された場合つけるもの。 , "txt"
pofn->lpstrInitialDir = lpInitdir ;
pofn->lpstrFile = lpszRet ;
pofn->nMaxFile = maxbuf ;
pofn->lpstrFileTitle = NULL ;
pofn->nMaxFileTitle = 0 ;
pofn->lpstrTitle = lpTitle ;
return ;
}
//-- 2004/Oct/17
#define CXRC( rc ) ((rc).right - (rc).left )
#define CYRC( rc ) ((rc).bottom - (rc).top )
//--
#define UNFOLDRC( rc ) (rc).left , (rc).top , (rc).right , (rc).bottom
#define ReflectFrameChanged(hwnd) \
SetWindowPos( (HWND)(hwnd) , NULL , 0 , 0 , 0 , 0 , \
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | \
SWP_NOACTIVATE | SWP_FRAMECHANGED )
#define ResizeWindow( hwnd , cx , cy ) \
SetWindowPos( (hwnd) , NULL , 0 , 0 , (cx) , (cy) , SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE ) ;
#define IsFloating(hdlg) ( GetWindowStyle((HWND)(hdlg)) & WS_CAPTION )
void TabCtrl_AdjustClientWnd( HWND hTab , HWND hClient , BOOL bRepaint ) ;
#define PathExists( file ) ( GetFileAttributes( (char *)(file) ) != 0xFFFFFFFF )
#define PathDirectory( file ) ( GetFileAttributes( (char *)(file) ) == FILE_ATTRIBUTE_DIRECTORY )
#define PathIsFile( file ) ( ! PathDirectory( (file) ) )
#define PathDriveSpecified( file ) \
( *( (file ) + 1 ) && *((file) + 1 ) == ':' && *( (file ) + 2 ) && *( (file ) + 2 ) == '\\' )
#define LastPtr( str ) ( char *)( (*(str) ? (str) + strlen( str ) - 1 : NULL ))
// 文字列の最後の文字( \0の手前。) 文字列が 0 の場合は、NULL を返し、代入しようとすれば不正アクセスとなる。
#define SetLastSymbol( str , c ) \
*( (str) + strlen( (str) ) - 1 ) = (c)
#define LBIT( i ) ( 1 << (i) )
//ツールバー用追加マクロ
#define CheckToolButton( hwndtoolbar , idbutton , fCheck ) \
SendMessage( (HWND)hwndtoolbar , TB_CHECKBUTTON , (WPARAM)(idbutton) , MAKELONG( (fCheck) , 0 ) )
#define IsToolButtonChecked( hwndtoolbar , idbutton ) \
SendMessage( (HWND)hwndtoolbar , TB_ISBUTTONCHECKED , (WPARAM)(idbutton) , 0L )
#define ToolBar_InsertButton( htool , ibtn , ptbbtn ) \
SendMessage( (htool) , TB_INSERTBUTTON , (ibtn) , ( LPARAM ) (ptbbtn) )
#define ToolBar_DeleteButton( htool , ibtn ) \
SendMessage( (htool) , TB_DELETEBUTTON , (ibtn) , 0 )
#define ToolBar_GetExtendedStyle( htool ) \
SendMessage( (htool) , TB_GETEXTENDEDSTYLE , 0L , 0L )
#define ToolBar_SetExtendedStyle( htool , dwexstyle ) \
SendMessage( (htool) , TB_SETEXTENDEDSTYLE , 0L , (dwexstyle) )
#define ToolBar_GetRect( htool , iItem , lprc ) \
SendMessage( (htool) , TB_GETRECT , (WPARAM)(iItem) , (LPARAM)(lprc) )
//ステータスバーマクロ
#define StatusBar_SetText( hwnd , wp , text ) \
SendMessage( (hwnd) , SB_SETTEXT , (WPARAM)(wp) , (LPARAM)(text) )
#define AppStatus( wp , text ) \
SendMessage( hStatus , SB_SETTEXT , (WPARAM)(wp) , (LPARAM)(text) )
#define RectToSmallRect( psmallrc , prc ) \
{ \
((SMALL_RECT *)(psmallrc))->Left = ((RECT *)(prc))->left ; \
((SMALL_RECT *)(psmallrc))->Top = ((RECT *)(prc))->top ; \
((SMALL_RECT *)(psmallrc))->Right = ((RECT *)(prc))->right ; \
((SMALL_RECT *)(psmallrc))->Bottom = ((RECT *)(prc))->bottom ; \
}
inline HANDLE CreateTemporalFile
( char *name , char *lpszFullpath )
{
// name に、つけたい名前、
// szFullpath は、フルファイル名を受け取る。
HANDLE ret ;
char szTempPath[MAX_PATH] ;
if( ! GetTempPath( MAX_PATH , szTempPath ))
{
*lpszFullpath = '\0' ;
return INVALID_HANDLE_VALUE ;
}
if( ! GetTempFileName( szTempPath , name ,
0, lpszFullpath )) return INVALID_HANDLE_VALUE ;
ret = CreateFile
( lpszFullpath , GENERIC_WRITE | GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE , NULL , OPEN_ALWAYS
, FILE_ATTRIBUTE_TEMPORARY , NULL ) ;
return ret ;
}
// マクロ的テンプレート
template <typename P> P *eoc( P *p )
{ // eoc == 'e'nd _'o'f _'c'hain
if( ! p ) return NULL ;
P *beg = p ; // エンドレスチェインの場合の処置
while( p->next )
{ p = p->next ; if( p == beg ) break ; }
return p ;
}
const char *HrToString( HRESULT hr )
{
static char ret[256] ;
#define REGISTERMSG( hr ) case ((hr)) : return #hr
#define REGISTERMSG2( hr , x ) case ((hr)) : return x
switch( hr )
{
REGISTERMSG2( 0x80070003 , "PATH NOT FOUND !" ) ;
REGISTERMSG( S_OK ) ;
/* STG_E_XXX (winerror.h) */
REGISTERMSG( STG_E_INVALIDFUNCTION ) ;
REGISTERMSG( STG_E_FILENOTFOUND ) ;
REGISTERMSG( STG_E_PATHNOTFOUND ) ;
REGISTERMSG( STG_E_TOOMANYOPENFILES ) ;
REGISTERMSG( STG_E_ACCESSDENIED ) ;
REGISTERMSG( STG_E_INVALIDHANDLE ) ;
REGISTERMSG( STG_E_INSUFFICIENTMEMORY ) ;
REGISTERMSG( STG_E_INVALIDPOINTER ) ;
REGISTERMSG( STG_E_NOMOREFILES ) ;
REGISTERMSG( STG_E_DISKISWRITEPROTECTED ) ;
REGISTERMSG( STG_E_SEEKERROR ) ;
REGISTERMSG( STG_E_WRITEFAULT ) ;
REGISTERMSG( STG_E_READFAULT ) ;
REGISTERMSG( STG_E_SHAREVIOLATION ) ;
REGISTERMSG( STG_E_LOCKVIOLATION ) ;
REGISTERMSG( STG_E_FILEALREADYEXISTS ) ;
REGISTERMSG( STG_E_INVALIDPARAMETER ) ;
REGISTERMSG( STG_E_MEDIUMFULL ) ;
REGISTERMSG( STG_E_PROPSETMISMATCHED ) ;
REGISTERMSG( STG_E_ABNORMALAPIEXIT ) ;
REGISTERMSG( STG_E_INVALIDHEADER ) ;
REGISTERMSG( STG_E_INVALIDNAME ) ;
REGISTERMSG( STG_E_UNKNOWN ) ;
REGISTERMSG( STG_E_UNIMPLEMENTEDFUNCTION ) ;
REGISTERMSG( STG_E_INVALIDFLAG ) ;
REGISTERMSG( STG_E_INUSE ) ;
REGISTERMSG( STG_E_NOTCURRENT ) ;
REGISTERMSG( STG_E_REVERTED ) ;
REGISTERMSG( STG_E_CANTSAVE ) ;
REGISTERMSG( STG_E_OLDFORMAT ) ;
REGISTERMSG( STG_E_OLDDLL ) ;
REGISTERMSG( STG_E_SHAREREQUIRED ) ;
REGISTERMSG( STG_E_NOTFILEBASEDSTORAGE ) ;
REGISTERMSG( STG_E_EXTANTMARSHALLINGS ) ;
REGISTERMSG( STG_E_DOCFILECORRUPT ) ;
REGISTERMSG( STG_E_BADBASEADDRESS ) ;
REGISTERMSG( STG_E_DOCFILETOOLARGE ) ;
REGISTERMSG( STG_E_NOTSIMPLEFORMAT ) ;
REGISTERMSG( STG_E_INCOMPLETE ) ;
REGISTERMSG( STG_E_TERMINATED ) ;
/* E_XXX (winerror.h) */
REGISTERMSG( E_UNEXPECTED ) ;
REGISTERMSG( E_NOTIMPL ) ;
REGISTERMSG( E_OUTOFMEMORY ) ;
REGISTERMSG( E_INVALIDARG ) ;
REGISTERMSG( E_NOINTERFACE ) ;
REGISTERMSG( E_POINTER ) ;
REGISTERMSG( E_HANDLE ) ;
REGISTERMSG( E_ABORT ) ;
REGISTERMSG( E_FAIL ) ;
REGISTERMSG( E_ACCESSDENIED ) ;
// REGISTERMSG( E_NOTIMPL ) ;
// REGISTERMSG( E_OUTOFMEMORY ) ;
// REGISTERMSG( E_INVALIDARG ) ;
// REGISTERMSG( E_NOINTERFACE ) ;
// REGISTERMSG( E_POINTER ) ;
// REGISTERMSG( E_HANDLE ) ;
// REGISTERMSG( E_ABORT ) ;
// REGISTERMSG( E_FAIL ) ;
// REGISTERMSG( E_ACCESSDENIED ) ;
REGISTERMSG( E_PENDING ) ;
default :
wsprintf( ret , "NO ENTRY %d(0x%x)" , hr , hr ) ;
break ;
}
#undef REGISTERMSG
#undef REGISTERMSG2
return ret ;
}
//
//
//
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
// ===========================================================================
// File: atl.h
//
// ===========================================================================
#ifndef __ATL_H__
#define __ATL_H__
#include <ole2.h> // #include "ole2.h"
// COM Smart pointers
template <class T>
class _NoAddRefReleaseOnCComPtr : public T
{
private:
STDMETHOD_(ULONG, AddRef)()=0;
STDMETHOD_(ULONG, Release)()=0;
};
//CComPtrBase provides the basis for all other smart pointers
//The other smartpointers add their own constructors and operators
template <class T>
class CComPtrBase
{
protected:
CComPtrBase()
{
p = NULL;
}
CComPtrBase(int nNull)
{
(void)nNull;
p = NULL;
}
CComPtrBase(T* lp)
{
p = lp;
if (p != NULL)
p->AddRef();
}
public:
typedef T _PtrClass;
~CComPtrBase()
{
if (p)
p->Release();
}
operator T*() const
{
return p;
}
T& operator*() const
{
return *p;
}
//The assert on operator& usually indicates a bug. If this is really
//what is needed, however, take the address of the p member explicitly.
T** operator&()
{
return &p;
}
_NoAddRefReleaseOnCComPtr<T>* operator->() const
{
return (_NoAddRefReleaseOnCComPtr<T>*)p;
}
bool operator!() const
{
return (p == NULL);
}
bool operator<(T* pT) const
{
return p < pT;
}
bool operator==(T* pT) const
{
return p == pT;
}
// Release the interface and set to NULL
void Release()
{
T* pTemp = p;
if (pTemp)
{
p = NULL;
pTemp->Release();
}
}
// Attach to an existing interface (does not AddRef)
void Attach(T* p2)
{
if (p)
p->Release();
p = p2;
}
// Detach the interface (does not Release)
T* Detach()
{
T* pt = p;
p = NULL;
return pt;
}
HRESULT CopyTo(T** ppT)
{
if (ppT == NULL)
return E_POINTER;
*ppT = p;
if (p)
p->AddRef();
return S_OK;
}
T* p;
};
template <class T>
class CComPtr : public CComPtrBase<T>
{
public:
CComPtr()
{
}
CComPtr(int nNull) :
CComPtrBase<T>(nNull)
{
}
CComPtr(T* lp) :
CComPtrBase<T>(lp)
{
}
CComPtr(const CComPtr<T>& lp) :
CComPtrBase<T>(lp.p)
{
}
T* operator=(T* lp)
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
}
T* operator=(const CComPtr<T>& lp)
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp));
}
};
// -- my_implimentation "CComQIPtr"
template <class T, const IID* piid = &__uuidof(T)>
class CComQIPtr : public CComPtr<T> //public CComPtrBase<T>
{
public:
CComQIPtr()
{
}
CComQIPtr(int nNull) :
CComPtrBase<T>(nNull)
{
}
CComQIPtr(T* lp) :
CComPtrBase<T>(lp)
{
}
CComQIPtr(const CComQIPtr<T,piid>& lp) :
CComPtrBase<T>(lp.p)
{
}
CComQIPtr(IUnknown* lp)
{
p=NULL;
if(lp != NULL)
lp->QueryInterface(*piid, (void **)&p);
}
T* operator=(T* lp)
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp ));
}
T* operator=(const CComQIPtr<T,piid>& lp)
{
return static_cast<T*>(AtlComPtrAssign((IUnknown**)&p, lp.p ));
}
T* operator=(IUnknown* lp)
{
return static_cast<T*>(AtlComQIPtrAssign((IUnknown**)&p, lp, *piid ));
}
};
// -- my_implimentation ends
#define IUNKNOWN_METHODS \
private: ULONG volatile m_dwRef; \
public: \
virtual ULONG STDMETHODCALLTYPE AddRef( void) { \
return (ULONG)InterlockedIncrement((volatile LONG*)&m_dwRef); } \
virtual ULONG STDMETHODCALLTYPE Release( void) { \
ULONG new_ref = (ULONG)InterlockedDecrement((volatile LONG*)&m_dwRef); \
if (new_ref == 0) { delete this; return 0; } return new_ref; } \
#define BEGIN_COM_MAP(t) \
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) \
{ \
if (ppvObject == NULL) \
{ \
return E_POINTER; \
}
#define COM_INTERFACE_ENTRY(i) \
if (riid == IID_##i) \
{ \
*ppvObject = (i*)this; \
this->AddRef(); \
return S_OK; \
}
#define END_COM_MAP() \
return E_NOINTERFACE; \
} \
virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; \
virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
template <const IID* piid>
class ISupportErrorInfoImpl : public ISupportErrorInfo
{
public:
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
{
return (riid == *piid) ? S_OK : S_FALSE;
}
};
inline IUnknown* AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
{
if (lp != NULL)
lp->AddRef();
if (*pp)
(*pp)->Release();
*pp = lp;
return lp;
}
inline IUnknown* AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
{
IUnknown* pTemp = *pp;
*pp = NULL;
if (lp != NULL)
lp->QueryInterface(riid, (void**)pp);
if (pTemp)
pTemp->Release();
return *pp;
}
class CComMultiThreadModelNoCS
{
public:
static ULONG WINAPI Increment(LONG *p) {return InterlockedIncrement(p);}
static ULONG WINAPI Decrement(LONG *p) {return InterlockedDecrement(p);}
};
//Base is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
template <class Base>
class CComObject : public Base
{
public:
typedef Base _BaseClass;
// Set refcount to -(LONG_MAX/2) to protect destruction and
// also catch mismatched Release in debug builds
~CComObject()
{
m_dwRef = -(LONG_MAX/2);
}
//If InternalAddRef or InternalRelease is undefined then your class
//doesn't derive from CComObjectRoot
STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
static HRESULT WINAPI CreateInstance(CComObject<Base>** pp);
};
template <class Base>
HRESULT WINAPI CComObject<Base>::CreateInstance(CComObject<Base>** pp)
{
ATLASSERT(pp != NULL);
if (pp == NULL)
return E_POINTER;
*pp = NULL;
HRESULT hRes = E_OUTOFMEMORY;
CComObject<Base>* p = NULL;
p = new CComObject<Base>();
if (p != NULL)
{
hRes = NOERROR;
}
*pp = p;
return hRes;
}
// the functions in this class don't need to be virtual because
// they are called from CComObject
class CComObjectRootBase
{
public:
CComObjectRootBase()
{
m_dwRef = 0L;
}
public:
LONG m_dwRef;
}; // CComObjectRootBase
template <class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
{
public:
typedef ThreadModel _ThreadModel;
ULONG InternalAddRef()
{
ATLASSERT(m_dwRef != -1L);
return _ThreadModel::Increment(&m_dwRef);
}
ULONG InternalRelease()
{
#ifdef _DEBUG
LONG nRef = _ThreadModel::Decrement(&m_dwRef);
if (nRef < -(LONG_MAX / 2))
{
ATLASSERT(0);
}
return nRef;
#else
return _ThreadModel::Decrement(&m_dwRef);
#endif
}
}; // CComObjectRootEx
typedef CComMultiThreadModelNoCS CComObjectThreadModel;
typedef CComObjectRootEx<CComObjectThreadModel> CComObjectRoot;
#endif // __ATL_H__