تفاوت برنامه نویسی MFC و WIN32 در ویژوال سی
نوشته شده توسط مدیر سایت دوشنبه 23 خرداد 1390 ساعت 12:30
پروژه های Win32
با تعریف پروژه win32 به طور پیش فرض فایل سرآیهی windows.h به پروژه شما اضافه شده، فایلهای lib لازم (مثل user32.lib و kernel32.lib) هم در تنظیمات پروژه اضافه شده و تقریبا تمام توابع لازم برای کار با پنجره ها در اختیار شما قرار می گیرد. اگر این کارها را به صورت دستی در یک پروژه کنسول ساده انجام دهید نیازی به تعریف پروژه win32 ندارید!
پروژه های
MFC
به کمک این نوع پروژه شما می توانید، منو، دیالوگ، نوار ابزار و حتی ریبون (ویژوال استودیو 2010) را به صورت دیداری طراحی کنید و فقط کدهای لازم برای مدیریت رویدادها (مثل کلیک روی یک منوی خاص) را می نویسید. در این نوع پروژه کلاسهایی مثل CImage برای کار با تصاویر، CButton برای کار با دکمه، CFont برای کار با قلمهای ویندوز، CMenu برای منوها و ده ها کلاس متنوع دیگر وجود دارد که برنامه نویسی تحت ویندوز را بسیار تسهیل می کند.
با همه این تفاسیر کار کردن با پروژه های MFC نسبت به زبانهایی مثل #C و ویژوال بیسیک بسیار سخت تر است! به عنوان مثال در #C به محض ساختن یک Text Box با نام edit1 متغیری با همین نام در اختیار شما قرار می گیرد که به راحتی می توانید با آن کار کنید (متن آن را بخوانید یا تغییر دهید یا رنگ آن را عوض کنید) لیکن در MFC باید یک متغیر به آن تخصیص دهید و یا با دستوری مثل GetDlgItem پنجره مربوط به آن Text Box را گرفته و سپس با آن کار کنید. آن هم نه همه کاری! مثلا کارهای ساده ای مثل تغییر رنگ یک کنترل در MFC به سختی پشتک بارو زدن است! کاری که در سایر زبانها در زمان طراحی قابل انجام است. البته همین امر هم سبب شده که برنامه های نوشته شده با ویژوال سی نسبت به سایر زبانها بسیار سریعتر باشند (هر زبان را بهر کاری ساختند!)
جبران گذشته و رهایی از سردرگمی
آخرین به روز رسانی در شنبه 24 ارديبهشت 1390 ساعت 11:50 نوشته شده توسط مدیر سایت شنبه 17 ارديبهشت 1390 ساعت 09:07
نظر یکی از کاربران
" با سلام خواهش میکنم مطالبم را بخوانید و کمکم کنید چون من واقعا سر در گم شدم دانشجوی ترم اول مهندسی فناوری اطلاعات مقطع ارشد هستم لیسانسم را در دانشگاه ازاد در رشته نرم افزار گرفتم اما به علت مشکلاتی میخوام از صفر شروع کنم میخوام بدونم چه مطالبی از مبتدی تا پیشرفته را باید یک کارشناس نرم افزار بداند مثلا یکیش نرم افزار matlab لطفا خواهشا از ابتدا بگید که چی بخونم تا بتونم رامو پیدا کنم چه نرم افزار هایی -چه زبان هایی برنامه نویس -چه کارهایی باید بلد باشم."
این سوال یکی از مراجعین سایت است که البته سوال بسیاری از دیگر مراجعین هم بوده و احتمالا هست. با توجه به اینکه هر روز با دانشجویان سر و کار دارم می دانم که این یکی از بزرگترین مشکلات دانشجویان است. در این نوشته قصد ریشه یابی و ارائه راه حلی در خور وسع خودم دارم.
می گویند دکتر شریعتی به دانشجویانش می گفت پاسخهایی را می پسندم که ناشی از تفکر باشد نه کپی متن کتاب!
جوزدگی و دور هم بودن: مشکل دانشجویان در حین تحصیل
مشکل از آنجا آغاز می شود که در نظام آموزشی ما دانش آموزان و حتی دانشجویان وادار به تفکر نمی شوند. غالب تکالیف، تقلیدی است. شما باید کتابی را بخوانید و همان را پس بدهید. هیچگاه تشویق نمی شوید که درباره زندگیتان، آینده شغلی تان، کاربرد رشته خودتان در جامعه تفکر کنید. کم می شود که مثلا استادی یا معلمی بگوید این درسی را که می خوانید چه کاربردی دارد و در آینده به چه دردتان خواهد خورد. دانشجویان هم سراغ چنین سوالاتی کمتر می روند و چون دَورهم هستند و خوشند نگران نیستند. حدیث است که می فرماید وقتی بلایی همه گیر شد، تحملش آسان می شود. این موضوع شده است بلای همه گیر، دانشجویان به یکدیگر نگاه می کنند می بینند دوستانشان دارند گیم بازی می کنند یا قهوه تلخ می بینند، آنها هم تشویق می شوند که بی خیال باشند. (البته همیشه استثنائاتی وجود دارند)
نکته بسیار قابل توجه این است که زمانی که فارغ التحصیل می شویم، تازه دوهزاریمان می افتد که ای داد بیداد. چهار سال درس خواندیم ولی ظاهرا چیزی یاد نگرفته ایم!! ممکن است مدتی هم غصه بخوریم... حالا چند راه حل وجود دارد:
- یکی اینکه با همین تحصیلات آبدوغ خیاری برویم و در جایی استخدام شویم؛ این جا اگر دولتی بود که زیاد به جایی بر نمی خورد و باز دور هم هستیم! لیکن اگر خصوصی بود ناچاریم تازه شروع کنیم به یادگیری
- دوم اینکه بی خیال درس شده و شغل آزاد انتخاب کنیم، آن هم از نوعی که هیچ ارتباطی با تحصیلاتمان نداشته باشد، مثلا بقالی، نصب پرده، صوتی تصویری و امثال اینها. (این کار را اگر چهار سال زودتر انجام می دادیم شاید بهتر هم بود!)
- سوم اینکه ادامه تحصیل دهیم، شاید که جبران مافات کنیم. این کار البته دردسرش بیشتر است، چون در فوق لیسانس دیگر خودمان هم وظیفه ای داریم. باید برای هر درسی یکی دو سمینار ارائه دهیم، باید با کتابهای لاتین کنار بیاییم و حتی پیش فرضهای استاد را هم بپذیریم. مثلا استاد انتظار دارد که اولین پروژه درسی را با نرم افزار متلب (MATLAB) بنویسیم ولی ما تا کنون نمی دانستیم که به جز زبان پاسکال و C زبان دیگری هم برای برنامه نویسی هست!
بحث من در مورد افرادیست که گزینه سوم را انتخاب می کنند:
ماهی را هر وقت از آب بگیرید تازه است
مهم نیست که چهار سال گذشته و ما درس زیادی یاد نگرفته ایم. مهم این است که دوستانی یافته ایم، زندگی اجتماعی را آموخته ایم و مهمتر این که تجربیات خوبی اندوخته ایم. مهمترین تجربه همین که باید خودمان به فکر خودمان باشیم، باید کاری بکنیم. اینکه فهمیده ایم با کپی کردن و تقلب شاید بتوان نمره گرفت لیکن نمی توان یاد گرفت. ضمن اینکه در جامعه که نمی توان همیشه تقلب کرد. در مقابل استاد و سایر دانشجویان که نمی شود از روی کاغذ مطلبی را ارائه داد. برنامه هایی که نیاز خودمان و جامعه است را که همیشه نمی توان دانلود کرد.
در دوره کارشناسی ارشد یا هر زمان دیگری که متوجه شدید باید کاری کرد، آستینهای همت را بالا بزنید و دست به کار شوید. ببینید چه چیزهایی نیاز رشته شما و جامعه است، آنها را یاد بگیرید. دقت کنید که از این پس باید به فکر آینده شغلی هم باشید، لذا در یک موضوعی که نیاز جامعه هست سعی کنید متبحر شوید. مثلا در رشته نرم افزار می بینید برنامه نویسی تحت وب نیاز امروز بسیاری از سازمانهاست، آن را خوب یاد بگیرید. در رشته برق، گرایش الکترونیک، می بینید شرکتهای سخت افزاری نیاز مبرمی به افرادی که با FPGA آشنا هستند دارند، آن را بیاموزید. اصلا گاهی اوقات خوب است شما ابتدا علاقه خودتان را بیابید، و برای آن کار پیدا کنید و پایان نامه تان را هم در راستای آن تعریف کنید! این حالت ایده آل است. بگذارید تجربه شخصی ام را خیلی مختصر برایتان بگویم:
تجربه شخصی در دوران کارشناسی ارشد
من در یک شرکت مخابراتی مشغول کار بودم، تقریبا با رشته درسی ام (الکترونیک) و علاقه شخصی ام (برنامه نویسی) سازگار بود. لیکن زمانی که به دنبال تعیین استاد راهنما بودم با یکی از اساتید دانشکده صحبت کردم. متوجه شدم علاقه زیادی به مبحث OCR و شناسایی الگو دارم. این شد که درسهای مرتبط را برداشتم (شبکه عصبی، شناسایی الگو و پردازش تصویر) آنگاه به دنبال شرکتی رفتم که در این زمینه کار می کرد. به زودی شغلم را عوض کردم! و پایان نامه ام را در همان زمینه ای تعیین کردم که در شرکت جدید مشغول کار شده بودم! با این کار در تمام مدت فوق لیسانس من تقریبا کارمند دائم آن شرکت هم بودم... همین اتفاق در دوران دکتری هم تکرار شد. به لطف خدا و توفیق حضور در شرکت مذکور، در چندین پروژه ملی در زمینه شناسایی الگو همکاری داشتم.
موانع سر راه
و آمّا! بدانید که اگر با پایه ضعیف وارد دوره کارشناسی ارشد شوید (مخصوصا در رشته های فنی) با موانع زیادی رو به رو خواهید شد. مثلا شما زبان انگلیسی تان خوب نیست، لیکن کتابها و مقالاتی که استادتان معرفی می کند انگلیسی است. شما با نرم افزارهای شبیه سازی و زبانهای برنامه نویسی آشنایی ندارید لیکن هر دو هفته باید یک پروژه تحویل دهید. شما در ریاضیات 1 و 2 ضعف دارید لیکن باید فرمول های عجیب و غریب پای تخته را با تکان سر بپذیرید. (یعنی ناچارید بپذیرید که لااقل پیش سایر دانشجویان کم نیاورید) اینها واقعا مشکل است؛ بنده دارم از نزدیک می بینم. لیکن باید جبران کرد. اگر الان جبران نکنید لابد در خدمت مقدس سربازی جبران خواهید کرد؟!
کوچک که بودم برایم پذیرفتن این حدیث خیلی سخت بود: ساعتی تفکر بهتر است از هفتاد سال عبادت. الان سالهاست که دیگر برایم سخت نیست!
موفق باشید
خوشه یابی با الگوریتم K میانگین در OpenCV
نوشته شده توسط مدیر سایت پنجشنبه 23 دی 1389 ساعت 18:58

#ifdef _CH_
#pragma package
#endif
#define CV_NO_BACKWARD_COMPATIBILITY
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include
#endif
#ifdef _DEBUG
#pragma comment (lib, "highguid.lib")
#pragma comment (lib, "cxcored.lib")
#else
#pragma comment (lib, "highgui.lib")
#pragma comment (lib, "cxcore.lib")
#endif
int main( int argc, char** argv )
{
#define MAX_CLUSTERS 5
CvScalar color_tab[MAX_CLUSTERS];
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
CvRNG rng = cvRNG(-1);
CvPoint ipt;
color_tab[0] = CV_RGB(255,0,0);
color_tab[1] = CV_RGB(0,255,0);
color_tab[2] = CV_RGB(100,100,255);
color_tab[3] = CV_RGB(255,0,255);
color_tab[4] = CV_RGB(255,255,0);
cvNamedWindow( "clusters", 1 );
for(;;)
{
char key;
int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
int i, sample_count = cvRandInt(&rng)%1000 + 1;
cv::Mat _points (sample_count, 2, CV_32FC1);
cv::Mat _clusters (sample_count, 1, CV_32SC1);
//cv::RNG& rng = cv::theRNG();
//rng.fill(_points, cv::RNG::NORMAL, param1, param2 );
for(int i = 0; i < sample_count; i++){
CvPoint center;
CvMat point_chunk;
center.x = cvRandInt(&rng)%img->width;
center.y = cvRandInt(&rng)%img->height;
}
CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
cluster_count = MIN(cluster_count, sample_count);
/* generate random sample from multigaussian distribution */
for( k = 0; k < cluster_count; k++ )
{
CvPoint center;
CvMat point_chunk;
center.x = cvRandInt(&rng)%img->width;
center.y = cvRandInt(&rng)%img->height;
cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
k == cluster_count - 1 ? sample_count :
(k+1)*sample_count/cluster_count, 1 );
cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
cvScalar(center.x,center.y,0,0),
cvScalar(img->width*0.1,img->height*0.1,0,0));
}
/* shuffle samples */
for( i = 0; i < sample_count/2; i++ )
{
CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f temp;
CV_SWAP( *pt1, *pt2, temp );
}
for(int i = 0; i < sample_count; i++){
_points.at(i, 0) = points->data.fl[i*2];
_points.at(i, 1) = points->data.fl[i*2+1];
}
//old OpenCV Style
//cvKMeans2( points, cluster_count, clusters,
// cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
// 5, 0, 0, 0, 0 );
//New OpenCV Style
cv::kmeans( _points, cluster_count, _clusters,
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
5, 0, 0);
cvZero( img );
for( i = 0; i < sample_count; i++ )
{
//int cluster_idx = clusters->data.i[i];
//ipt.x = (int)points->data.fl[i*2];
//ipt.y = (int)points->data.fl[i*2+1];
int cluster_idx = _clusters.at(i, 0);
ipt.x = (int)_points.at (i, 0);
ipt.y = (int)_points.at (i, 1);
cvCircle( img, ipt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 );
}
cvReleaseMat( &points );
cvReleaseMat( &clusters );
cvShowImage( "clusters", img );
key = (char) cvWaitKey(0);
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
break;
}
cvDestroyWindow( "clusters" );
return 0;
}
#ifdef _EiC
main(1,"kmeans.c");
#endif
لینک دانلود مستقیم OpenCV 2.2
آخرین به روز رسانی در شنبه 07 اسفند 1389 ساعت 19:02 نوشته شده توسط مدیر سایت چهارشنبه 15 دی 1389 ساعت 22:44
با توجه به مشکل غالب کاربران در دانلود OpenCV لینک مستقیم آخرین نسخه (تا این زمان) این کتابخانهی بینایی ماشین سازگار با visual c++ 2010 در اختیار کاربران قرار می گیرد. البته تغییراتی در ساختار سلسله مراتبی این کتابخانه رخ داده که با مراجعه به راهنمای آن متوجه خواهید شد.
با توجه به محدودیتهای سایت سورس فورج برای ایران: برای دانلود لینک زیر را کپی کنید (کلیک راست و copy link location یا مشابه آن) و در یکی از نرم افزارهای مدیریت دانلود مثل downthemall که از افزونه های فایرفاکس است بچسبانید.
دانلود OpenCV-2.2.0-win32-vs2010.exe (کلیک نکنید که احتمالا دانلود نمی شود، دستور بالا را بخوانید)
یک نکته اخلاقی هم در مورد سایت خدمت بازدیدکنندگان عزیز عرض کنم: این سایت برای این نیست که شما تمرین بگذارید و ما پاسخ تمرین شما را بدهیم. متاسفانه فروم هم نیست که انتظار داشته باشید سریعا به تمام سوالات شما پاسخ داده شود. تنها جایی است برای آموزش کاربردی زبان ++C به زبان شیرین فارسی. در اینجا هیچ نفع مادی مترتب کسی نیست. اینکه گاهی دیر به دیر به روز می شود به دلیل مشغله مدیر سایت است.
موفق باشید.
پردازش تصویر به کمک OpenCV : لبه یابی و تغییر اندازه
آخرین به روز رسانی در پنجشنبه 04 آذر 1389 ساعت 23:21 نوشته شده توسط مدیر سایت
در مثال قبل، نحوه استفاده از OpenCV را آموختیم. اکنون قصد داریم برنامه ای برای یافتن لبه های تصویر و تغییر اندازه آن بنویسیم. OpenCV توابع زیادی برای کار با تصاویر دارد. در این مثال از 5 تابع cvCanny، cvSobel، cvResize، cvConvertScale و cvSplit استفاده خواهیم کرد که هر کدام را اگر یک تازه کار بخواهد بنویسد شاید چند روز یا حتی چند هفته وقت بگیرد.
خوب بهتر است به کد برنامه نگاهی بیندازیم:
نکته: به دلیل خطاهای غیر قابل پیش بینی که در کلاسهای c++ معرفی شده در نسخه 2.1 اتفاق می افتد، فعلا از خیر این کلاسها می گذریم و از همان توابع C آن استفاده می کنیم.
// in the name of allah
// The second OpenCV example
// Working with some image processing functions like edge detectors
// Developed by http://www.P30CodeNevis.ir
// 2010-11-25
#include "cv.h"
#include "highgui.h"
//Canny Edge Detector
IplImage* doCanny( IplImage* in, double lowThresh, double highThresh, int aperture)
{
if(in->nChannels != 1)
return(0); //Canny only handles gray scale images
IplImage* out = cvCreateImage( cvGetSize(in), IPL_DEPTH_8U, 1 );
cvCanny( in, out, lowThresh, highThresh, aperture );
return( out );
};
//Sobel Edge Detector
IplImage* doSobel( IplImage* in, int xOrder, int yOrder, int aperture)
{
if(in->nChannels != 1)
return(0); //Sobel only handles gray scale images
IplImage* temp = cvCreateImage( cvGetSize(in), IPL_DEPTH_16S, 1 );
IplImage* out = cvCreateImage( cvGetSize(in), IPL_DEPTH_8U, 1 );
cvSobel( in, temp, xOrder, yOrder, aperture );
cvConvertScale(temp, out);
cvReleaseImage(&temp);
return( out );
};
//Image Resize
IplImage* doResize( IplImage* in, int filter = CV_INTER_LINEAR )
{
IplImage* out = cvCreateImage(
cvSize( in->width/2, in->height/2 ), in->depth, in->nChannels );
cvResize( in, out, filter );
return( out );
};
int main( int argc, char** argv ) {
const char* imagename = argc > 1 ? argv[1] : "camera-man.jpg";
IplImage* img = cvLoadImage(imagename);
IplImage* resized = doResize(img);
IplImage* g = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
cvSplit(img, 0, g, 0, 0);
IplImage* cedge = doCanny(g, 50, 175, 3);
IplImage* sedge = doSobel(g, 0, 1, 3);
cvShowImage("Original", img);
cvShowImage("Green Channel", g);
cvShowImage("Resized", resized);
cvShowImage("Canny Edge", cedge);
cvShowImage("Sobel Edge", sedge);
cvSaveImage("Green channel.jpg", g);
cvSaveImage("Resized.jpg", resized);
cvSaveImage("Canny Edge.jpg", cedge);
cvSaveImage("Sobel Edge.jpg", sedge);
cvWaitKey(0);
// Release memory and destroy window
cvReleaseImage( &resized );
cvReleaseImage( &g );
cvReleaseImage( &cedge );
cvReleaseImage( &sedge );
cvReleaseImage( &img );
cvDestroyWindow( "Original" );
cvDestroyWindow( "Green Channel" );
cvDestroyWindow( "Resized" );
cvDestroyWindow( "Canny Edge" );
cvDestroyWindow( "Eobel Edge" );
return(0);
}
بارگذاری تصویر مانند مثال قبل، یا از طریق خط فرمان است و یا تصویر camera-man.jpg که باید در مسیر برنامه باشد. برای تغییر اندازه تصویر اصلی از تابع cvResize استفاده می کنیم. این تابع که هم اسم آن و هم رفتار آن مطابق توایع مرسوم تغییر اندازه است، سه پارامتر می گیرد: اولی تصویر ورودی، دومی تصویر خروجی که میزان تغییر مقیاس هم از روی همین تصویر تعیین می شود و سومی نوع الگوریتم است که یکی از چهار مقدار CV_INTER_LINEAR, CV_INTER_NN, CV_INTER_AREA, CV_INTER_CUBIC را می گیرد. این مقادیر به ترتیب برای الگوریتمهای bilinear و binearest neighboura و pixel area resampling و bicubic می باشد. مناسب ترین روش از نظر سرعت و کیفیت همان bilinear است.
توابع cvCanny و cvSobel دو لبه یاب معروف هستند که اولی بار محاسباتی بسیار زیادی نسبت به سوبل دارد. در هر دو مورد، تصویر ورودی باید خاکستری باشد، لذا به کمک cvSplit ما تنها کانال green تصویر را گرفته و به عنوان ورودی به این توابع ارسال می کنیم. کانال green نماینده خوبی از سطح خاکستری تصویر است.
لبه یاب سوبل سه پارامتر می گیرد، اولی نحوه مشتق گیری در راستای افقی (0: عدم مشتق گیری، 1: مشتق اول و 2: مشتق دوم) دومی نحوه مشتق گیری در راستای عمودی و سومی اندازه فیلتر که غالبا 3*3 استفاده می شود. بهتر است تصویر خروجی لبه یاب سوبل از نوع IPL_DEPTH_16S باشد چرا که محاسبات داخلی منجر به مقادیری بیش از یک بایت می شود و لذا برای هر پیکسل از یک عدد صحیح 16 بیتی علامت دار استفاده می کنیم. لیکن برای نمایش تصویر ناچاریم دوباره آن را به IPL_DEPTH_8U (هر پیکسل معادل یک عدد 8 بیتی بدون علامت) برگردانیم که برای این کار از تابع cvConvertScale استفاده می کنیم.
لبه یاب کنی هم سه پارامتر می گیرد، دو تا آستانه پایین و بالا (هر کدام بین 0 و 255) و یکی اندازه فیلتری (مانند فیلتر سوبل) که در داخل canny استفاده می شود. جزئیات بیشتر را از اینجا بخوانید.
سایر کدهای برنامه برای نمایش و ذخیره سازی تصاویر و پاکسازی حافظه است که گمان نمی کنم نیاز به توضیح داشته باشد.
تصاویر خروجی برنامه:
تصویر ورودی: camera-man.jpg
تصویر خاکستری (کانال سبز): Green channel.jpg
تصویر لبه کنی: Canny Edge.jpg
تصویر لبه سوبل: Sobel Edge.jpg
تصویر کوچک شده: Resized.jpg
مطالب بیشتر...
- شروع کار با OpenCV
- استفاده از کتابخانه OpenCV به زودی
- کتابخانه پردازش تصویر CxImage
- کلاس بردار در سی پلاس پلاس
- مثال هفدهم - کار با فایل صوتی و کتابخانه FFTW در ویژوال C++
- مثال شانزدهم - برنامه نمایش تصویر MDI
- اسلاید: ساختار Document-View در MFC
- مطالعه موردی کلاسها: آرایه پویا
- تمرین ششم درس برنامه نویسی پیشرفته
- مثال پانزدهم: برنامه نمایش تصویر
- پروژه درس برنامه نویسی پیشرفته C++
- تفاوت ارسال پارامترهای تابع به صورت مقدار، ارجاع و اشاره گر
- سورس کد مثالهای 13 و 14 مربوط به مبحث MFC
- اسلاید: جلسات سوم و چهارم از MFC
- کلاسها در ++C: بخش سوم چگونگی تعریف اشیاء و استفاده از توابع عضو
- کلاسها در ++C: بخش دوم نحوه تعریف کلاس
- کلاسها در C++: بخش اول مقدمهای بر شیءگرایی
- سورس کد مثالهای یازدهم و دوازدهم - MFC
- تمرین پنجم درس برنامه نویسی پیشرفته
- اسلاید: کتابخانه MFC بخش دوم
JPAGE_CURRENT_OF_TOTAL




