PDA

View Full Version : سوال: استفاده از ماکروهای ATL and MFC String Conversion Macros



حسین محمدی
دوشنبه 31 فروردین 1388, 18:41 عصر
با سلام

من از ماکروی W2T استفاده می کنم ولی خطای زیر ظاهر می شود:


error C2065: '_lpw' : undeclared identifier
error C2065: '_convert' : undeclared identifier


چه هدر فایل یا ... را فراموش کرده ام؟

Nima_NF
دوشنبه 31 فروردین 1388, 22:16 عصر
هدر فایل های AtlBase.h و AtlConv.h

حسین محمدی
سه شنبه 01 اردیبهشت 1388, 09:07 صبح
من این هدر فایلها را اضافه کردم البته از USES_CONVERSAITION نیز استفاده کردم.
ولی اطلاعات را هنگامی که من توسط W2T تبدیل می کنم اشتباه تبدیل می شود.

ظاهرا در تشخیص CodePage اشتباه می کند.

اگر من پروژه خود را در حالت Multi-Byte کامپایل کنم خطا وجود دارد.
ولی اگر در حالت unicode تبدیل کنم خطا وجود ندارد.

Nima_NF
سه شنبه 01 اردیبهشت 1388, 19:05 عصر
احتمالا شما دارید در نسخه های جدید visual C++ کار می کنید، W2A و USES_CONVERSAITION و سایر ماکرو های مشابه برای نسخه ATL 3 هست.

در کامپایلرهای جدید از نسخه ATL 7 یا 8 استفاده کنید، یعنی از کلاس های این کار مانند CW2A و CA2WEX و ...
در MSDN بخش ATL 7 با نام ATL 7.0 String Conversion Classes and Macros را مطالعه کنید. (http://msdn.microsoft.com/en-us/library/87zae4a3%28VS.80%29.aspx)

مثال ها برای تبدیل:



CW2A pstr1( L"My Text" );

در مثال فوق مستقیم در هرجایی که خواستید pstr1 را استفاده کنید (مانند یک رشته اسکی)

یا به شکل زیر در اشاره گر بریزید (ولی در انتها باید حافظه را delete کنید):



LPCSTR pstr2 = CW2A( L"My Text" );

حسین محمدی
یک شنبه 13 اردیبهشت 1388, 12:38 عصر
من از visual studio 2008 استفاده می کنم.

و نمی دانم کدام یکی از این ماکروها برای 3 و کدامیک برای 7 می باشد.

می توانید راهنمایی کنید؟

فوری است.

با تشکر

Nima_NF
یک شنبه 13 اردیبهشت 1388, 13:23 عصر
توابع و ماکرو های ATL های جدید معمولا کلاس هستند مانند CA2AEX, CA2WEX, CW2AEX ,CW2WEX ,CT2AEX, CW2TEX, CW2CTEX, CT2CAEX ,CW2A
دقت کنید اکثرا کلاس هستند و متدهایی دارند.

به لینکی که در پست قبل دادم بروید، در انتهای صفحه در بخش ATL 3.0 String Conversion Macros یک جدول وجود دارد که ماکرو های ATL3 گفته شده است، از آن ها استفاده نکنید.

با این حال داخل فایل atlconv.h اطلاعات بیشتری وجود دارد.

حسین محمدی
یک شنبه 13 اردیبهشت 1388, 16:51 عصر
توضیح مختصر در مورد پروژه من

Accounts یک شی از کلاسی است که از کلاس Command<CDynamicParameterAccessor> ارث می برد.



CDBPropSet propset(DBPROPSET_ROWSET);
Accounts.GetRowsetProperties(&propset);
hr = Accounts.Create(Accounts.Session(), _T("SELECT AccountID, FirstName, LastName, Description FROM dbo.Accounts"));
//prepare to get parameters info
hr = Accounts.Prepare();
void *pDummy;
hr = Accounts.BindParameters(&(Accounts.m_hParameterAccessor), Accounts.m_spCommand, &pDummy, true, true);
hr = Accounts.Open(&propset, NULL, true);

DBCOLUMNINFO *spColumnInfo;
OLECHAR *pStringsBuffer;
DBORDINAL nColumns = 0;
hr = Accounts.CDynamicAccessor::GetColumnInfo( Accounts.m_spRowset, &nColumns, &spColumnInfo, &pStringsBuffer );
if (SUCCEEDED(hr) && GetTreeCtrl().DeleteAllItems())
{
hr = Accounts.MoveFirst();
if (SUCCEEDED(hr))
{
while (SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET)
{
TCHAR szFullName[258]; //m_FirstName(128) + Space(1) + m_LastName(128) + Zero Character(1)
DBLENGTH dwFirstNameLength;
_tcscpy_s(szFullName, 129, CW2T((WCHAR*)Accounts.GetValue(_T("FirstName"))));
_tcscat_s(szFullName, 130, _T(" "));
_tcscat_s(szFullName, 258, CW2CT((WCHAR*)Accounts.GetValue(_T("LastName"))));
HTREEITEM hItem = GetTreeCtrl().InsertItem(szFullName);
GetTreeCtrl().SetItemData(hItem, *(LONG*)Accounts.GetValue(_T("AccountID")));
hr = Accounts.MoveNext();
}
}
}


من برنامه را trace کردم و مشکل در هنگامی است که دستور زیر



BOOL bFailed=(0 == ::WideCharToMultiByte( nConvertCodePage, 0, psz, nLengthW, m_psz, nLengthA, NULL, NULL ));


اجرا می شود.

در این حالت پارامتر ها عبارتند از:

پارامتر اول (nConvertCodePage)
CP_THREAD_ACP یا 3

پاارمتر سوم (psz)
محمد

پارامتر چهارم (nLengthW)
5

پارامتر ششم (m_psz)
یک عبارت مقدار دهی نشده (مقدار زباله)

پارامتر هفتم (nLengthA)
20

که بعد از اجرای این دستور m_psz برابر ???? می شود.

پروژه من هنگامی که در حالت Unicode کامپایل میشود درست اجرا می شود ولی در حالتی که در حالت Multibyte است با اشکال مواجه میشود.

سیستم عامل من Vista است.


مشکل از کجاست؟

Nima_NF
یک شنبه 13 اردیبهشت 1388, 17:34 عصر
وقتی می خواهید از رشته های یونیکد استفاده کنید ( در اینجا فارسی) حتما باید پروژه در حالت unicode کامپایل شود. WideCharToMultiByte هم باید در حالت یونیکد کامپایل شود تا درست کار کند.
اگر پروژه ای در حالت Multibyte کامپایل شود، کامپایلر اصلا معنای کارکترهای یونیکد که دو بایتی هستند را نمی فهمد و هیچ کارکتر فارسی را پشتیبانی نمی کند، لذا تمام بایت های رشته ها با مقادیر اشتباه پر می شوند.

Nima_NF
یک شنبه 13 اردیبهشت 1388, 18:22 عصر
ضمنا موضوع دیگر این هست که اگر قرار هست کلمات فارسی را تبدیل کنید به جای CP_THREAD_ACP در پارامتر اول از CP_UTF8 یا شماره code page زبان استفاده کنید. مثلا شماره 1256 برای زبان عربی.

لیست code page زبان ها برای فلگ اول در این لینک (http://msdn.microsoft.com/en-us/library/dd317756%28VS.85%29.aspx)




char m_psz[30];
WCHAR strW[5] = L"محمد";

WideCharToMultiByte( 1256 , 0, strW, -1, m_psz, 30, NULL, NULL );

// or use CP_UTF8:
// WideCharToMultiByte( CP_UTF8, 0, strW, -1, m_psz, 30, NULL, NULL );

به شکل فوق فارسی درست تبدیل می شود.

(MSDN را که بررسی کردم دیدم بیان شده است که نسخه ای از این تابع برای ویندوز های قدیمی بدون پشتیبانی یونیکد نیز پیاده سازی شده است، احتمالا اگر به شکل فوق عمل کنید و نوشته را صراحتا به جای _T با حرف L مشخص کنید بتوانید در حالت غیر multibyte هم درست کامپایل کنید.)