درباره نویسنده
اصغر میرزائی
  • صفحه نخست
  • آرشیو وبلاگ
  • تماس با من
  • فید وبلاگ
نویسندگان وبلاگ
  • اصغر میرزائی
مطالب اخیر
  • Ellipsis - Variable Argument
  • بازگشت دوباره!!
  • نمايش Menu روی Tray Icon
  • Modless Dialog
  • Tray Icon
  • DialUp
  • نوشتن برنامه Dialup
  • مقدمه ای بر پردازش تصوير
  • تبديل تاريخ ميلادی و شمسی به هم
  • پردازش تصوير برای RoboCup(Middle Size)
  • کلاس های جالب ويژوال سی۷ - فتوشاپ بسازيم !
  • ۱۳۸٢/۱٢/۱٧
  • ۱۳۸٢/۱٢/۱٦
  • ۱۳۸٢/۱٢/۱۳
  • ۱۳۸٢/۱٠/۱٩
  • در ويژوال سی چگونه سيستم را reset ,shutdown,logoff,...کنيم ؟
  • استفاده از فايلهای DLL بدون نياز به Header File اصلی انها
  • تغيير رنگ پس زمينه ديالوگ
  • فرستادن ايميل
  • لينك آموزشي
  • ساختن برنامه نصب کننده( InstallShield )
  • تا حالا سعی کرديد توی Visualc++6 فارسی بنويسيد ؟
  • ۱۳۸٢/۳/۱۱
  • ۱۳۸٢/٢/٢٢
  • ۱۳۸٢/٢/۱٧
  • Message Programming
  • ۱۳۸٢/٢/۱٤
  • چرا در بعضی برنامه ها سيستم هنگ می کنه ؟
  • جواب به سوالات
  • سال نو مبارک
کلمات کلیدی مطالب
     
آرشیو وبلاگ
  • عناوین مطالب
  • خرداد ۸٤
  • مهر ۸۳
  • شهریور ۸۳
  • امرداد ۸۳
  • تیر ۸۳
  • خرداد ۸۳
  • اردیبهشت ۸۳
  • اسفند ۸٢
  • دی ۸٢
  • آبان ۸٢
  • شهریور ۸٢
  • امرداد ۸٢
  • خرداد ۸٢
  • اردیبهشت ۸٢
  • فروردین ۸٢
  • اسفند ۸۱
  • بهمن ۸۱
  • آذر ۸۱
  • آبان ۸۱
  • مهر ۸۱
  • شهریور ۸۱
  • امرداد ۸۱
دوستان من
     
کدهای اضافی کاربر


------- . : . : . : Visual C++.NET آموزش : . : . : . -------
Ellipsis - Variable Argument
نویسنده: اصغر میرزائی - ۱۳۸٤/۳/۳

سلام

بازگشت گودزيلا

فکر نمی کردم انقدر بشه اما يه غيبت طولانی شد. به هر حال اميدوارم  ديگه پيش نياد!!

--------------------------------------------------------

اما بعد...

داشتم فکر می کردم با چی شروع کنم که ياد (...) يا همون Ellipsis افتادم. شايد ديده باشيد که ازش توی برنامه نويسی استفاده کرده باشن و شايد هم به احتمال زياد اصلا نديده باشيد که خوب يه جورايی طبيعی هستش٬ چون کاربرد رايجی نداره و کمتر استفاده ميشه.

(...) رو اصطلاحا ميگن Ellipsis .

کجا ها کاربرد داره ؟

- جاهايی که نمی خوان محدوديتی در تعداد و نوع پارامترهای پاس شده باشه!

مثلا تابع printf رو در نظر بگيريد که يک رشته ورودی بهش پاس می کنيد که می تونه علاوه بر اين رشته٬ يک سری پارامتر دلخواه با هر نوع ممکن رو که دوست داريد در محلی که در رشته مشخص کرديد چاپ بشه٬ رو هم می تونيد به عنوان ورودی بهش پاس کنيد يا نکنيد.

شايد بگيد خب که چی؟!؟!

- اگه يکم دقت کنيد می بينيد که توی تعريف تابع بايد نام و نوع ورودی ها کاملا مشخص و معتبر باشه و تعداد نامحدود عملا نمی تونه داشته باشه!! پس چطوری تابعی مثل printf بنويسيم؟؟

اينجاست که Ellipsis ضرورت پيدا ميکنه.

حالا چطوری استفاده ميشه ؟

- خيلی ساده!
شکل کلی تعريف تابع با استفاده از Ellipsis به شکل زير هستش:

void MyFunction(int x,...);

البته اين يک نمونه مثال هستش. به کمک x که قبل از ... اومده به آدرس اولين متغيير بعدی پاس شده به تابع بر روی stack دسترسی خواهيم داشت٬ اما اين اصلا ربط مستقيم به نوع و مقدار x نداره و کامپايلر از اين تنها برای دسترسی به متغيير های بعدی استفاده می کنه که اصطلاحا Variable Argument می گن.

ابتدا بايد يک متغيير از نوع va_list تعريف کنيد. بعد بايد از تابع va_start به شکل زير استفاده کنيد:

va_list vl;

va_start( vl, &x);

حالا از طريق متغيير vl به متغييرهای پاس شده دسترسی خواهيد داشت٬ مثلا به شکل زير:

double d;

d = va_arg( vl, double );

خط بالا اولين متغيير رو که فرض کردم double هستش بر می گردونه و برای متغييرهای احتمالی بعدی به همين شکل ادامه پيدا می کنه.

در پايان استفاده بايد تابع va_end رو صدا بزنيد :

va_end( vl );

حالا ديگه به چه شکل دوست داريد استفاده کنید با خودتونه!

اميدوارم به دردتون بخوره!

موفق باشيد

نظرات ()



بازگشت دوباره!!
نویسنده: اصغر میرزائی - ۱۳۸۳/٧/٢٢

جمعه، ۳۰ اردیبهشت، 1384 -- ساعت ۱:۴۷

سلام

اگه خدا بخواد قصد دارم ادامه بدم!

اميدوارم تنبلی نکنم !!

خوش باشيد

نظرات ()



نمايش Menu روی Tray Icon
نویسنده: اصغر میرزائی - ۱۳۸۳/٦/٢٠

سلام

قرار بود نمايش Menu روی Tray Icon رو بگم.

کار ساده تر از اين حرفاست.

توی کلاس ديالوگتون بصورت public  تابع زير رو اضافه کنيد :

 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

اين برا اينه که message ها رو handle کنيم (ديگه چون يکم عکس گذاشتن سختم بود دستی ميگم انجام بديد که عکس نخواد )

حالا  تابع زير رو توی کد اصلی بنويسيد که قراره menu رو اينجا نمايش بديم :

LRESULT اسم کلاس برنامه تونDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{

 return CDialog::WindowProc(message, wParam, lParam);
}

حالا بايد يه menu ساخته باشيد و با استفاده از ID اون و چند خط کد زير می تونيد menu رو نمايش بديد (اينجا من از پيغام کليک راست روی آيکون استفاده کردم) :

   CMenu mymenu,*pmenu;
   if (message == myicon.uCallbackMessage)
   {
  if(lParam==WM_RBUTTONDOWN)
  {
   mymenu.LoadMenu(IDR_MENU1);
   pmenu=mymenu.GetSubMenu(0);
   CPoint pos;
   #ifdef _WIN32_WCE
    pos = CPoint(GetMessagePos());
   #else
    GetCursorPos(&pos);
   #endif
   ::TrackPopupMenu(pmenu->m_hMenu, TPM_TOPALIGN, pos.x, pos.y, 0,
       this->GetSafeHwnd(), NULL);
  mymenu.DestroyMenu();
  pmenu->DestroyMenu();
  }

**اما myicon.uCallbackMessage چيه ؟!

اگه يادتون باشه برای ايجاد tray icon يه شی با  اسم myicon ساخته بوديم همونه  که uCallbackMessage رو توش ست کرده بوديم.

**IDR_MENU1 هم ID منوی مورد نظر هستش.

همين !!

اما توی مطلب بعدی از اينکه چجوری پيغامهای ويندوز رو وقتی که ديالوگ ما فعال نيست بگيريم صحبت می کنم.

خوش باشيد

نظرات ()



Modless Dialog
نویسنده: اصغر میرزائی - ۱۳۸۳/٥/۱۳

سلام

مطلب امروز در مورد پنجره های Modless هستش.

شايد بگيد يعنی چی !!!

اگه دقت کرده باشيد معمولا پيغامهای خطا يا هشدار دهنده به شکلی هستند که وقتی نمايش داده ميشوند ديگه نمی تونيد به پنجره برنامه اصلی دسترسی داشته باشيد و غير فعال می شود تا زمانی که به اون پيغام خطا يا هشدار يه جواب مناسب (حالا از OK گرفته تا Yes و No ) بدهيد. به اينگونه نمايش يه پنجره (همون پيغام خطا خودش يه پنجره هستش ديگه) روش Modal ميگن.

حالا بعضی مواقع نياز داريد که پنجره هايی رو نشون بديد که همزمان نياز باشه که هم روی پنجره اصلی برنامه و هم روی اين پنجره جديد نمايش داده شده کار شود (يه مثال خوب و روشن برای اين نوع ياهو مسنجر هستش که اين صفحه اصلی رو در ابتدا داريد و به ازای هر PM که باز می کنيد يا به شما داده ميشه يه پنجره باز ميشه که بايد بتونيد روی هرکدوم که خواستيد کار کنيد ) به اين نوع نمايش پنجره Modless ميگن.

کار خيلی راحت و کوتاه هستش.

اول که خب بايد ديالوگتون و کد های مربوط رو بنويسيد!

هر موقع خواستيد از يه ديالوگ يه ديالوگ ديگه رو نمايش بديد کافی هستش که چند خط زير رو بنويسيد :

CDialog *MyDlg=new CDialog();

MyDlg->Create(IDD_ABOUTBOX,0);

MyDlg->ShowWindow(true);

توضيحات :

IDD_ABOUTBOX مربوط به ID ديالوگ اصلی شما ميشود که حالا اينجا من برای سادگی کار خواستم ديالوگ About که بصورت پيش فرض ساخته ميشه رو نشون بدم !

اگه دقت کنيد تابع Create از شما ۲ تا پارامتر می خواد که با اولی آشنا شديد. اما دومی چيه ؟! بايد بگم اگه دومی رو مقدار ۰ يا همون NULL قرار بديد فرض ميکنه که پدر ديالوگی که ميخواهيد نمايش بديد اون ديالوگی هستش که از اون قصد نمايش اين ديالوگ جديد رو داريد و يکم با اينکه يه ديالوگ مستقل باشه فرق ميکنه (مثلا اگه ديالوگ اصلی رو مينيمم کنيد اين هم همراه اون مينيمم ميشه و اگه اين جديد رو مينيمم کنيد ديگه روی TaskBar ديده نميشه و مثل پروژهای MDI انگار که ديالوگ اصلی شما برنامه Container اصلی باشد ديالوگ جديد به همون شکل مينيمم ميشه ! حالا تست کنيد بهتر دستگيرتون ميشه!).  اما اگه بخواهيد عين صفحه PM در YAHOO! Messeneger وقتی ديالوگ جديد رو نمايش ميديد بر روی TaskBar هم ديده بشه بايد يه اشاره گر به Desktop بهش بديد که با تابع GetDesktopWindow که هيچ پارامتر ورودی هم نياز نداره اين کار ميسر ميشه.

همين !

خوش باشید

 

نظرات ()



Tray Icon
نویسنده: اصغر میرزائی - ۱۳۸۳/٥/۱

سلام

امروز از TrayIcon ميگم براتون.

چی هست ؟!

کنار ساعت ويندوز رو نگاه کن چند تا ازشون ميبينی . آره همون آيکون ها رو می گم.

خيلی کار راحتيه!

اول خط زير يادتون نره :

#include <SHELLAPI.H>

برا اينکار يه آيکون درست کنيد يا از همون آيکون استاندارد فعلا استفاده کنيد و ID اونو از قسمت resource  و در پوشه Icon پيدا کنيد. بصورت استاندارد يه آيکون با ID 

(IDR_MAINFRAME) ايجاد ميکنه که آيکون MFC هستش.

حالا بايد در اين ۳ خط زير هر جا   IDI_ICON1 که آی دی انتخابی من برا آيکون مورد نظرم بوده, آی دی آيکون خودتون رو بگذاريد:

HICON hIcon;

HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(IDI_ICON1),RT_GROUP_ICON);

hIcon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);

hIcon رو قراره به يه تابع بديم که بدونه کدوم آيکون رو ميخواهيم برامون بگذاره.

حالا يه متغيير بصورت زير تعريف کنيد :

NOTIFYICONDATA myicon;

با اين متغيير يکسری اطلاعات به تابع مربوط به کار مورد نظر ما پاس ميشه.

حالا مقاديری که بايد مقدار دهی کنيد رو دونه دونه جلوی هر خط مثال زير توضيح ميدم :

myicon.hWnd=this->GetSafeHwnd();//هندلی به ديالوگی می خوايد پيغامهای ويندوز به اون منتقل بشه که برای استفاده از منو روی آيکون مورد نظر اهميت پيدا ميکنه

myicon.cbSize=sizeof(NOTIFYICONDATA);//رو که مقدار دهی ميکنه که هميشه همينهNOTIFYICONDATAاندازه متغيير

myicon.uFlags=NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;// امکاناتی که می خوايد اين آيکون داشته باشه از جمله پيغامهای ويندوز و نمايش خود آيکون و نمايش بالون محتوی توضی در مورد آيکون

myicon.uCallbackMessage=IDD_DIALOG1;// آی دی ديالوگی که پيغامهای ويندوز به اون منتقل ميشه

myicon.hIcon=hIcon;//متغييری که بالا برای آيکون خودمون تنظيم کرديم

myicon.szInfoTitle="My Title";//تيتر بالونی که روی آيکون ايجاد ميشه

myicon.szInfo="My information";// متن اصلی بالونی که روی آيکون ايجاد ميشه

 myicon.szTip="Mouse over information (Tool Tip !)";// متنی که وقتی موس روی آيکون نگهداشته ميشه نشمون ميده

myicon.uTimeout=20;// زمانی که بالون نمايش داده ميشه

Shell_NotifyIcon(NIM_ADD,&myicon);// با اين تابع آيکون در کنار ساعت نمايش داده ميشه

برای مخفی کردن ديالوگ هم از تابع زير استفاده کنيد :

ShowWindow(SW_HIDE);

** نکته:

بايد بگم که موارد بالون و ToolTip در VisualC++6 با مشکل همراه هستش و ظاهرا support نمی کنه و بايد اين رو توی VisualC++.NET انجام بديد !

نمايش منو بر روی اين آيکون رو توی مطلب بعدی توضيح ميدم.

موفق باشيد

نظرات ()



DialUp
نویسنده: اصغر میرزائی - ۱۳۸۳/٤/٢٤

سلام

امروز ميخوايم يه برنامه ساده بنويسيم که يوزر و پسورد و شماره تلفن بگيره و خودش شروع کنه به اينترنت وصل بشه.

اول که بايد يه پروژه جديد بسازيد و ۳ تا edit box برای اطلاعات يوزر و پسورد و شماره تلفن.

اولين کاری که بايد کنيد اينه که ۱-۲ کلاس رو به پروژه اضافه کنيد که با ۲خط زير انجام ميديد:

#include "ras.h"
#include "raserror.h"

حالا ۲ تا دکمه بگذاريد برای وصل شدن و قطع ارتباط.

برای وصل شدن از چند خط ساده زير استفاده کنيد که هر خط رو جداگانه توضيح ميدم:

 RASDIALPARAMS rdParams;// متغييری(شئی) است برای دادن اطلاعات مورد نياز برای کانکت به اينترنت
 rdParams.dwSize = sizeof(RASDIALPARAMS); 
 rdParams.szEntryName[0] = '\0';
 lstrcpy( rdParams.szPhoneNumber, m_strPhoneNumber );//در اين قسمت شماره تلفن را مقدار دهی ميکنيم
 rdParams.szCallbackNumber[0] = '\0';
 lstrcpy( rdParams.szUserName, m_strUserName );//در اين قسمت يوزررا مقدار دهی ميکنيم
 lstrcpy( rdParams.szPassword, m_strPassword );//در اين قسمت پسورد را مقدار دهی ميکنيم
 rdParams.szDomain[0] = '\0';

HRASCONN hRasConn = NULL;//اين متغيير برای نسبت دادن يک هندل به اين کانکشن در صورت موفقيت خوهد بود که بتوان در آينده از آن استفاده کرد مثلا آنرا قطع کرد
    DWORD dwRet = RasDial( NULL, NULL, &rdParams, 0L, NULL, &hRasConn );//در اين قسمت شروع به شماره گيری ميکند و نتيجه شماره گيری بازگردانده می شود که در صورت موفقيت صفر و در غير اين صورت شماره خطلا خواهد بود
    if ( dwRet == 0 )  return true;
    char  szBuf[256];
 if ( RasGetErrorString( (UINT)dwRet, (LPSTR)szBuf, 256 ) != 0 )//اگر منجر به خطا شد با استفاده از شماره خطا متن خطا را بدست آمرده نمايش می دهيم و کانکشن را می بنديم
  wsprintf( (LPSTR)szBuf, "Undefined RAS Dial Error (%ld).", dwRet );
 RasHangUp( hRasConn );
 MessageBox( (LPSTR)szBuf, "Error", MB_OK | MB_ICONSTOP );
 return false;

تا ايجا نحوه خيلی ساده اتصال رو ديديم. حالا بايد در صورت نياز امکان قطع کردن رو هم فراهم کنيم که اونم به سادگی کد زير هستش:

 RASCONN ras[20];
 DWORD  dSize, dNumber;
 char  szBuf[256];
 
 connected=false;
 ras[0].dwSize = sizeof( RASCONN );
 dSize = sizeof( ras );   // Get active RAS - Connection
 DWORD  dwRet = RasEnumConnections( ras, &dSize, &dNumber );
 if ( dwRet != 0 )
 {
  if ( RasGetErrorString( (UINT)dwRet, (LPSTR)szBuf, 256 ) != 0 )
   wsprintf( (LPSTR)szBuf, "Undefined RAS Enum Connections error (%ld).", dwRet );
  MessageBox( (LPSTR)szBuf, "RasHangUp", MB_OK | MB_ICONSTOP );
  return false;
 }
 bool bOK = true;
 for( DWORD dCount = 0;  dCount < dNumber;  dCount++ )
 {    // Hang up that connection
  HRASCONN hRasConn = ras[dCount].hrasconn;
  DWORD dwRet = RasHangUp( hRasConn );
  if ( dwRet != 0 )
  {
   char  szBuf[256];
   if ( RasGetErrorString( (UINT)dwRet, (LPSTR)szBuf, 256 ) != 0 )
    wsprintf( (LPSTR)szBuf, "Undefined RAS HangUp Error (%ld).", dwRet );
   MessageBox( (LPSTR)szBuf, "RasHangUp", MB_OK | MB_ICONSTOP );
   bOK = false;
  }
 }
 return bOK;

با اين ۲ تابع ساده ميتونيد به اينترنت متصل شيد. اما نکاتی که هست اينه که :

اولا اصلا کانکشن ويندوزی ساخته نميشه.

دوماً اينکه ايکون اتصال هم نمايش داده نميشه و دست شمارو باز ميگذاره که هرجور دوست داريد اعمال سليقه کنيد.

اميد ئارم مفيد باشه براتون

ان شاالله مطللب بعدی درمورد Tray Icon (آيکون کنار ساعت ويندوز) خواهد بود.

موفق باشيد.

نظرات ()



نوشتن برنامه Dialup
نویسنده: اصغر میرزائی - ۱۳۸۳/۳/۳٠

سلام

توی مطلب بعدی می خوام در مورد نوشتن يک برنامه برای وصل شدن به اينترنت(Dialup) صحبت کنم. تو اين برنامه مستقل از ساختن هر گونه connection به اينترنت (يا هر سرور منتظر) متصل می شويد.

قصد دارم اگه فرصت کنم در مورد ايجاد آيکون در کنار ساعت (Try Icon) و نحوه نمايش بالون استاندارد ويندوز روی اون و چگونگی هندل کردن پیغامهای اين آيکون به برنامه اصلی و نحوه نمايش منو روی اون مطلب بنويسم .

چه آينده پرباری!!!!

خوش باشيد

نظرات ()



مقدمه ای بر پردازش تصوير
نویسنده: اصغر میرزائی - ۱۳۸۳/۳/٢٦

سلام

امروز يکم از پردازش تصوير صحبت ميکنم.

اولين گام پردازش تصوير کار با رنگ نقاط (pixel) هستش. اما بايد بگم توی حالت عادی شما ۳ درجه رنگی از ۳ رنگ اصلی آبی و سبز و قرمز برای هر نقطه داريد که با کم و زياد شدن شدت هر مولفه اصلی رنگ حاصل تغيير ميکنه . اما تو پردازش تصوير اين فرمت اصلا به درد نمی خوره ! دليلش اينه که شما معمولا نياز به تشخيص يه محدوده رنگی خاص داريد مثلا رنگ حول و حوش صورتي, حالا با ۳ رنگ اصلی چطور می خوايد اين محدوده رو تعيين کنيد ؟! ميشه گفت محاله ممکنه  يا بهتر بگم اصلا عقلانی نيست دنبالش بريد.!!!

پس بايد دنبال شيوه ای برای اون باشيم!

برای هر رنگ ما ۳ مشخصه می تونيم نام ببريم :

۱- نام رنگ (چيز بهتری گير نيووردم بهش بگم -> Hue ) :

اين يعنی اينکه رنگ چيه ! مثلا ميگی آبی يا آبی يکم متمايل به سبز يا ....

۲- شدت رنگ :

اگه دقت کرده باشيد هر رنگ ميتونه پر رنگ يا کم رنگ باشه اما ماهيت ذاتی اون يه چيزه و فقط کم رنگ تر يا پررنگ تر شده به اين ميگن -> Saturation

۳- روشنايی يا تيرگی رنگ :

يه رنگ رو می تونيد بهش نور بتابونيد که روشناييش زياد بشه يا نور رو کم کنيد که روشناييش کم بشه که ميتونه انقدر کم بشه که سياه بشه !! به اين ميگن->Intensity

اميدوارم تونسته باشن خوب برسونم منظورم چيه !

پس يه حوضه جديد که الهام گرفته از چشم هستش رو باهاش آشنا شديم که کار روی رنگها برای تصميم گيری روی مشخصات اون رو راحت ميکنه. به اين حوضه رنگی اصطلاحا HSI ميگن که مخفف اون ۳کلمه بالاست. شکل زير نمودار تغييرات رنگ رو با توجه به اين ۳ مولفه نشون ميده:

H بين ۰ تا ۳۶۰ هستش يعنی از قرمز تا سبز ۱۲۰ درجه و از سبز تا آبی ۱۲۰درجه و از آبی تا قرمز ۱۲۰ درجه در جهت خلاف جهت حرکت عقربه های ساعت.

S بين ۰ تا ۱۰۰ هستش که از کم رنگ (۰) تا پر رنگ (۱۰۰)

I از ۰ تا ۱۰۰ هستش يعنی از تاريک(۰) تا روشن(۱۰۰)

چند نمونه از رنگها در ۲ حوضه مذکور :

رنگ

RGB مقادیر

HSI مقادير

سياه

(255,255,255)

(0,0,0)

سفيد

(255,255,255)

(0,0,100)

قرمز

(255,0,0)

(0,100,100)

سبز

(0,255,0)

(120,100,100)

آبی

(0,0,255)

(240,100,100)

!  قهوه ای

(64,128,128)

(180,50,50)

حالا نياز به اين داريم که RGB مربوط به هر نقطه را به HSI تبديل کنيم که رابطش رو به صورت سی نوشتم که r,g,b همون ۳ رنگ آبی و سبز و قرمز هر نقطه هستش:

int min,max;

/////////////////////

if(r>g)

{

max=r;

min=g;

}

else

{

max=g;

min=r;

}

if(b>max)

max=b;

if(b<min )

min=b;

////////////////////

if(max==0)

{

i=0;

s=0;

h=0;

}

else

{

i=max*100/255;

s=(max-min)*100/max;

h=180*acos((((r-g)+(r-b))/2)/sqrt(pow(r-g,2)+(r-b)*(g-b)))/3.1415;

if(b>g)

h=360-h;

}

نظرات ()



تبديل تاريخ ميلادی و شمسی به هم
نویسنده: اصغر میرزائی - ۱۳۸۳/٢/٢٧

سلام

اگه احتمالا تاحالا سعی کرده باشيد که يه برنامه ديتابيس بنويسيد به مشکل تاريخ شمسی بر خورديد!!!

ديتابيسها از تاريخ ميلادی پشتيبانی ميکنن و از تاريخ شمسی ما بدشون مياد !!!

توابع تبديلی رو نت ميشه پيدا کرد مثلا يکی تو سايت www.iranasp.net معرفی شده که شديدا تو سالهای کبيسه باگ و قاط داره.

تقريبا تمام کسانی که از روشهايی مبتنی بر يکسری آرايه برای محاسبه استفاده کردند دچار مشکل هستن و اصلا قابل اعتماد نيستن. اما روشی که من ميخوام معرفی کنم کاملا علمی و بر پايه محاسبات علم نجوم و تقويم شناسی پياده سازی شده و اصلا مو لا درزش نميره!!(ميگی نه تستش کن)

اما يه نکته که هست اينه که چون من کارهای ديتابيس رو با Delphi انجام ميدم اينو بصورت ۲ تا تابع دلفی نوشتم و چون نيازی به استفاده تو ويژوال سی نداشتم به سی تاحالا ننوشتم و اگه فرصت شد و خواستيد مينويسم و تو وب لاگ ميگذارم.

۲ تا تابع يکی برای تبديل ميلادی به شمسی و ديگری برای تبديل شمسی به ميلادی هستش و خروجی اينها رو من يه رشته در نظر گرفتم ::

function Miladi2Shamsi(iyear,imonth,iday:integer):string;
var
aa:string ;
jdn,jdn2,depoch,cycle,cyear,ycycle,aux1, aux2,yday:integer;
epbase,epyear,mdays:integer;
Const PERSIAN_EPOCH = 1948321 ;
begin
    If ((iYear > 1582) Or ((iYear = 1582) And (iMonth > 10)) Or ((iYear = 1582) And (iMonth = 10) And (iDay > 14))) Then
        jdn:=((1461*(iYear+4800+((iMonth-14) div 12))) div 4)+((367*(iMonth-2-12*(((iMonth-14) div 12)))) div 12)-((3*(((iYear+4900+((iMonth-14) div 12)) div 100))) div 4)+iDay-32075
    Else
    jdn := 367 * iYear - ((7 * (iYear + 5001 + ((iMonth - 9)  div  7)))  div  4) + ((275 * iMonth)  div  9) + iDay + 1729777;
    epbase:=475-474;
    epyear:= 474 + (epbase Mod 2820)  ;
    mdays:= (1 - 1) * 31 ;
    jdn2:=1+mdays+ Trunc(((epyear*682)-110)/ 2816)+(epyear-1)*365+Trunc(epbase / 2820)*1029983+(PERSIAN_EPOCH-1);
    depoch:=jdn-jdn2;
    cycle:= Trunc(depoch / 1029983);
    cyear:= depoch Mod 1029983 ;
    If cyear = 1029982 Then
        ycycle:=2820
    Else
    begin
        aux1:=Trunc(cyear / 366);
        aux2:=cyear Mod 366;
        ycycle:=round(((2134*aux1)+(2816*aux2)+2815) / 1028522)+aux1+1;
    End;
    iYear:=ycycle+(2820*cycle)+474;
    If iYear <= 0 Then
        iYear:=iYear-1;
    If iYear>=0 Then
        epbase:=iYear-474
    Else
        epbase:=iYear-473;
    epyear:=474+(epbase Mod 2820);
    mdays:=(1-1)*31;
    jdn2:=1+mdays+Trunc(((epyear*682)-110)/ 2816)+(epyear-1)*365 +Trunc(epbase / 2820)*1029983+(PERSIAN_EPOCH-1);
    yday:=(jdn-jdn2)+1;
    If yday <= 186 Then
        iMonth:= -Sign(yday / 31) * round(-Abs(yday / 31))
    Else
        iMonth:= -Sign(((yday - 6) / 30)) * round(-Abs((yday - 6) / 30));
    If iYear >= 0 Then
        epbase:=iYear-474
    Else
        epbase:=iYear-473;
    epyear:=474+(epbase Mod 2820);
    If iMonth <= 7 Then
        mdays:=(iMonth-1)*31
    Else
        mdays:=(iMonth-1)*30+6;
    jdn2:=1+mdays+Trunc(((epyear*682)-110)/ 2816)+(epyear-1)*365+ Trunc(epbase / 2820)*1029983+(PERSIAN_EPOCH-1);
    iDay:=(jdn-jdn2)+1;
     aa:=inttostr(iYear)+'/'+inttostr(iMonth)+'/'+inttostr(iDay);
Miladi2Shamsi:=aa;
end;

-------------------------------------------------------------------------------

//////////////////////////Shamsi2Miadi
function Shamsi2Miladi(iyear,imonth,iday:integer):string;
var
    aa:string;
    epbase,epyear,mdays,jdn,l,n,i,j,k:integer;
    Const PERSIAN_EPOCH = 1948321;
begin
    If iYear >= 0 Then
        epbase:=iYear-474
    Else
        epbase:=iYear-473;
    epyear:=474+(epbase Mod 2820);
    If iMonth <= 7 Then
        mdays:=((iMonth)-1)*31
    Else
        mdays:=((iMonth)-1)*30+6;
   jdn:=iDay+mdays+Trunc(((epyear*682)-110) div 2816)+(epyear-1)*365+trunc(epbase div 2820)*1029983+(PERSIAN_EPOCH-1);
   If (jdn > 2299160) Then
   begin
        l := jdn + 68569;
        n := ((4 * l) div 146097);
        l := l - ((146097 * n + 3) div 4);
        i := ((4000 * (l + 1)) div 1461001);
        l := l - ((1461 * i) div 4) + 31 ;
        j := ((80 * l) div 2447);
        iDay := l - ((2447 * j) div 80);
        l := (j div 11) ;
        iMonth := j + 2 - 12 * l ;
        iYear := 100 * (n - 49) + i + l;
    end
   Else
    begin
    j := jdn + 1402;
    k := ((j - 1) div 1461);
    l := j - 1461 * k   ;
    n := ((l - 1) div 365) - (l div 1461) ;
    i := l - 365 * n + 30  ;
    j := ((80 * i) div 2447)   ;
    iDay := i - ((2447 * j) div 80)   ;
    i := (j div 11)   ;
    iMonth := j + 2 - 12 * i   ;
    iYear := 4 * k + n + i - 4716  ;
   end;
     aa:=inttostr(iYear)+'/'+inttostr(iMonth)+'/'+inttostr(iDay);
     Shamsi2Miladi:=aa;
end;

اميدوارم مفيد باشه براتون (که حتما خواهد بود)

موفق باشيد

ميرزائی

نظرات ()



پردازش تصوير برای RoboCup(Middle Size)
نویسنده: اصغر میرزائی - ۱۳۸۳/٢/٢٠

سلام

يه دوست عزيزمون درمورد Image Processing برای روبوتهای RoboCup که احتمالا منظورشون Middle Size  بوده سوال کرده بودن.

بايد بگم ما يه ۲ سالی مشغول اين کار بوديم و هر سال بنا به مشکلاتی نا کام از اعزام شديم: سال اول پول گير نيوورديم که ۴ تا روبوت باقيمونده رو بسازيم و سال بعد يعنی همين امسال که برای GermanOpen می خواستيم اعزام بشيم درست ۲ روز قبل اعزام سفارت آلمان لطف کرد آب پاکی ريخت رو دستمون که ويزا نداد البته تقصير ما هم بود !! چون تو دانشگاه و بعدشم نظام وظيفه کلی به مشکل خورديم و پاسپورتها خيلی دير آماده شد. خلاصش رو بگم قسمت نشد بريم حالا تا سال بعد خدا چی بخواد.

تو اين کار پردازش تصوير هم خب قاعدتا داشتيم و اگه سوالی داشتيد ميل بزنيد تا بيشتر صحبت کنيم. اما برای شروع بگم کتاب Digital Image Processing -Richard.C Gonzalez رو يه جورايی حتما بايد بخونيد تا با مبانی پردازش تصوير آشنا بشيد.

مويد

نظرات ()



مطالب قدیمی تر »