GME  13
CommonMfc.h
Go to the documentation of this file.
00001 
00002 #ifndef MGA_COMMONMFC_H
00003 #define MGA_COMMONMFC_H
00004 
00005 #ifndef MGA_COMMONSMART_H
00006 #include "CommonSmart.h"
00007 #endif
00008 
00009 #include "afxtempl.h"
00010 #include "comdef.h"
00011 
00012 // --------------------------- CString
00013 
00014 inline void CopyTo(const CStringA &s, BSTR *b) { CopyTo(s, s.GetLength(), b); }
00015 inline void CopyTo(const CStringW &s, BSTR *b) { *b = CComBSTR(s).Detach(); }
00016 inline void CopyTo(const CStringA &s, VARIANT *v) { CopyTo(s, s.GetLength(), v); }
00017 inline void CopyTo(const CStringA &s, CComBstrObj &a) { CopyTo(s, s.GetLength(), a); }
00018 inline void CopyTo(const CStringW &s, CComBstrObj &a) { a = CComBstrObj(s); }
00019 inline void CopyTo(const CStringW &s, CComBSTR &a) { a = CComBSTR(s); }
00020 inline void CopyTo(const CStringA &s, CComVariant &a) { CopyTo(s, s.GetLength(), a); }
00021 
00022 inline void CopyTo(BSTR b, CStringA &s)
00023 {
00024         int len = GetCharLength(b);
00025         CopyTo(b, s.GetBufferSetLength(len), len);
00026         s.ReleaseBuffer(len);
00027 }
00028 
00029 // Different name to avoid collision with wchar_t*
00030 inline void CopyBSTRTo(const BSTR b, CStringW& s)
00031 {
00032         int len = SysStringLen(b);
00033         memcpy(s.GetBufferSetLength(len*sizeof(wchar_t)), b, len*sizeof(wchar_t));
00034         s.ReleaseBuffer(len);
00035 }
00036 
00037 inline void CopyTo(const CComBstrObj& b, CStringW& s)
00038 {
00039         CopyBSTRTo(b.p, s);
00040 }
00041 
00042 inline void CopyTo(const CComBSTR& b, CStringW& s)
00043 {
00044         CopyBSTRTo(b.m_str, s);
00045 }
00046 
00047 inline void CopyTo(VARIANT &v, CStringA &s)
00048 {
00049         int len = GetCharLength(v);
00050         CopyTo(v, s.GetBufferSetLength(len), len);
00051         s.ReleaseBuffer(len);
00052 }
00053 
00054 inline void CopyTo(const CStringA &s, CComBSTR &b) { CopyTo(s, &b); }
00055 
00056 template<class char_t>
00057 class PutOutCString
00058 {
00059         typedef ::ATL::CStringT< char_t, StrTraitMFC_DLL< char_t > > CString_t;
00060 
00061 private:
00062         friend PutOutCString PutOut(CString_t &s);
00063 
00064         PutOutCString(CString_t &a) : s(a)
00065         {
00066                 ASSERT( &s != NULL ); 
00067         }
00068 
00069 public:
00070         operator BSTR *() { return PutOut(b); }
00071         
00072         ~PutOutCString()
00073         {
00074                 CopyTo(b, s);
00075         }
00076 
00077 private:
00078         // to prevent misuse
00079         PutOutCString();
00080         PutOutCString(const PutOutCString &a);
00081 
00082 private:
00083         CComBstrObj b;
00084         CString_t &s;
00085 };
00086 
00087 inline PutOutCString<char> PutOut(CStringA &s)
00088 {
00089         return PutOutCString<char>(s);
00090 }
00091 
00092 inline PutOutCString<wchar_t> PutOut(CStringW &s)
00093 {
00094         return PutOutCString<wchar_t>(s);
00095 }
00096 
00097 class PutInCString
00098 {
00099 public:
00100         template<class T>
00101         PutInCString(T t) { CopyTo(t, b); }
00102 
00103         template<>
00104         PutInCString(BSTR t) { b = t; }
00105         operator const CString &() { return b; }
00106         operator const TCHAR *() { return b; }
00107 
00108         CString b;
00109 };
00110 
00111 // --------------------------- CComObjPtrArray
00112 
00113 template<class ELEM>
00114 class CComObjPtrList : public CList< CComObjPtr<ELEM>, CComObjPtr<ELEM> >
00115 { };
00116 
00117 template<class ELEM>
00118 class CComObjPtrArray : public CArray< CComObjPtr<ELEM>, CComObjPtr<ELEM> >
00119 { };
00120 
00121 template<class COLL, class ELEM>
00122 void CopyTo(COLL *coll, CComObjPtrArray<ELEM> &array)
00123 {
00124         ASSERT( coll != NULL );
00125         ASSERT( array.GetSize() == 0 );
00126 
00127         long count = 0;
00128         COMTHROW( coll->get_Count(&count) );
00129         ASSERT( count >= 0 );
00130 
00131         array.SetSize(count);
00132 
00133         COMTHROW( coll->GetAll(count, (ELEM**)array.GetData()) );
00134 }
00135 
00136 template<class COLL, class ELEM>
00137 void CopyTo(const CComObjPtr<COLL> &coll, CComObjPtrArray<ELEM> &array) 
00138 {
00139         CopyTo((COLL*)coll, array); 
00140 }
00141 
00142 template<class COLL, class ELEM>
00143 void CopyTo(const CComPtr<COLL> &coll, CComObjPtrArray<ELEM> &array) 
00144 {
00145         CopyTo((COLL*)coll, array); 
00146 }
00147 
00148 template<class COLL, class ELEM>
00149 class PutOutArrayObj
00150 {
00151 public:
00152         PutOutArrayObj(CComObjPtrArray<ELEM> &a) : array(a) { array.RemoveAll(); }
00153         ~PutOutArrayObj() { ASSERT( coll != NULL); CopyTo(coll, array); }
00154 
00155         operator COLL **() { return PutOut(coll); }
00156 
00157         CComObjPtrArray<ELEM> &array;
00158         CComObjPtr<COLL> coll;
00159 };
00160 
00161 template<class COLL, class ELEM>
00162 PutOutArrayObj<COLL, ELEM> PutOut(CComObjPtrArray<ELEM> &coll)
00163 {
00164         return coll;
00165 }
00166 
00167 // --------------------------- CArray<CComBstrObj, CComBstrObj&>
00168 
00169 typedef CArray<CComBstrObj, CComBstrObj&> CComBstrObjArray;
00170 
00171 inline void MoveTo(VARIANT *p, CComBstrObjArray &array)
00172 {
00173         ASSERT( array.GetSize() == 0 );
00174 
00175         array.SetSize(GetArrayLength(*p));
00176         MoveTo(p, array.GetData(), array.GetData() + array.GetSize());
00177 }
00178 
00179 inline void MoveTo(CComVariant &v, CComBstrObjArray &array) { MoveTo(&v, array); }
00180 
00181 inline void CopyTo(const VARIANT &p, CComBstrObjArray &array)
00182 {
00183         ASSERT( array.GetSize() == 0 );
00184 
00185         array.SetSize(GetArrayLength(p));
00186         CopyTo(p, array.GetData(), array.GetData() + array.GetSize());
00187 }
00188 
00189 inline void MoveTo(CComBstrObjArray &array, VARIANT *p)
00190 {
00191         ASSERT( p != NULL );
00192 
00193         MoveTo(array.GetData(), array.GetData() + array.GetSize(), p);
00194 }
00195 
00196 inline void CopyTo(const CComBstrObjArray &array, VARIANT *p)
00197 {
00198         ASSERT( p != NULL );
00199 
00200         CopyTo(array.GetData(), array.GetData() + array.GetSize(), p);
00201 }
00202 
00203 // --------------------------- CStringArray
00204 
00205 inline void CopyTo(VARIANT p, CStringArray &array)
00206 {
00207         ASSERT( array.GetSize() == 0 );
00208 
00209         CComBstrObjArray a;
00210         CopyTo(p, a);
00211 
00212         array.SetSize( a.GetSize() );
00213 
00214         for(int i = 0; i < a.GetSize(); ++i)
00215                 CopyTo(a[i], array[i]);
00216 }
00217 
00218 inline void CopyTo(const CStringArray &array, VARIANT *p)
00219 {
00220         CComBstrObjArray a;
00221         a.SetSize( array.GetSize() );
00222 
00223         for(int i = 0; i < array.GetSize(); ++i)
00224                 CopyTo(array[i], a[i]);
00225 
00226         CopyTo(a, p);
00227 }
00228 
00229 static CString CEditGetLine(const CEdit& edit, int line=-1) {
00230         int charsInLine = edit.LineLength(edit.LineIndex(line));
00231         // n.b. If the edit control is empty, GetLine call returns two null terminators
00232         if (charsInLine == 0)
00233                 return _T("");
00234         // n.b. CEdit::GetLine sends EM_GETLINE, so it must set the first word to the buffer size
00235         int charsInBuffer = charsInLine+1;
00236         if (charsInBuffer < sizeof(void*))
00237         {
00238                 charsInBuffer = sizeof(void*);
00239         }
00240         CString ret;
00241         // n.b. the CEdit::GetLine MSDN documentation is wrong: GetLine returns the number of characters (not bytes)
00242         // CEdit::GetLine returns (int)::SendMessage(...EM_GETLINE...) and the EM_GETLINE docs specify characters
00243         VERIFY(edit.GetLine(line, ret.GetBuffer(charsInBuffer), charsInBuffer) == charsInLine);
00244         ret.ReleaseBuffer(charsInLine);
00245         return ret;
00246 }
00247 
00248 static void GetFullPathName(const CString& path, CString& filename, CString& dirname) {
00249         TCHAR currentMgaPath[MAX_PATH];
00250         TCHAR* tcfilename;
00251         if (!GetFullPathName(path, MAX_PATH, currentMgaPath, &tcfilename) || tcfilename == 0) {
00252         } else {
00253                 filename = tcfilename;
00254                 *(tcfilename-1) = '\0';
00255                 dirname = currentMgaPath;
00256         }
00257 }
00258 
00259 static CString ConnStrToMgaPath(const CString& connStr) {
00260         ASSERT(connStr.Left(4).CompareNoCase(_T("MGA=")) == 0);
00261         return connStr.Right(connStr.GetLength() - 4);
00262 }
00263 
00264 
00265 // --------------------------- Error
00266 
00267 void DisplayError(const TCHAR *msg, HRESULT hr) NOTHROW;
00268 
00269 #define MSGTRY try
00270 
00271 #define MSGCATCH(MSG,CLEANUP) \
00272         catch(hresult_exception &e) \
00273         { \
00274                 { CLEANUP; } \
00275                 if (e.hr != E_MGA_CONSTRAINT_VIOLATION) \
00276                         DisplayError(MSG, e.hr); \
00277         } \
00278         catch(_com_error &e) { \
00279                 { CLEANUP; } \
00280                 _bstr_t error; \
00281                 if (e.Description() != _bstr_t()) \
00282                         error = e.Description(); \
00283                 else \
00284                         GetErrorInfo(e.Error(), error.GetAddress()); \
00285                 if (e.Error() != E_MGA_CONSTRAINT_VIOLATION) \
00286                         AfxMessageBox(_bstr_t(MSG) + ": " + error, MB_OK | MB_ICONSTOP); \
00287         }
00288 
00289 #endif//MGA_COMMONMFC_H