[戻る]

#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)&gtx , (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)&gtx , (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__