PDA

View Full Version : سوالی در مورد کردن بارگذاری bitmap :



A_Salimi
یک شنبه 05 اسفند 1386, 23:35 عصر
با سلام خدمت تمامی کاربران محترم این تایپیک :

میخواستم بدونم چرا پس از load کردن یک bitmap نمیشه مجددا روی اون bitmap دیگری رو لود کرد ؟

من در برنامه ای نیازدارم bitmap رو به دو صورت زیر بار کنم و هر کدام از این کدها در تابع مربوط به یک دکمه قرار دادم . . . اما چرا پس از یک بار لود شدن bitmap نمیشه مجددا bitmap دیگری لود کرد ؟




CPaintDC dc(this);
HBITMAP hBitMap=(HBITMAP)::LoadBitmap(AfxGetInstanceHandle (),MAKEINTRESOURCE(IDB_BITMAP1));
HDC hMemDC =::CreateCompatibleDC(NULL);
SelectObject(hMemDC,hBitMap);
::StretchBlt(dc.m_hDC,170,70,250,200,hMemDC,0,0,25 0,250,SRCCOPY);//
::DeleteDC(hMemDC);
::DeleteObject(hBitMap);









CPaintDC dc1(this);
HBITMAP hBitMap1=(HBITMAP)::LoadBitmap(AfxGetInstanceHandl e(),MAKEINTRESOURCE(IDB_BITMAP2));
HDC hMemDC1 =::CreateCompatibleDC(NULL);
SelectObject(hMemDC1,hBitMap1);
::StretchBlt(dc1.m_hDC,170,70,250,200,hMemDC1,0,0, 250,250,SRCINVERT);
::DeleteDC(hMemDC1);
::DeleteObject(hBitMap1);


ضمنا پس از ایجاد کامل bitmap چطور میشه اون رو حذف کرد ؟
ممنون میشم منو بی جواب نگذارید

Nima_NF
دوشنبه 06 اسفند 1386, 16:10 عصر
به چند نکته باید توجه کنید:
اگر حافظه اختصاص داده شده قابل آزاد شدن هست تابع ReleaseDC را باید فراخوانی کنید ، چون هر بار فقط یک عکس می تواند در DC قرار گیرد : (البته اگر در مورد استفاده از CPaintDC برای اختصاص حافظه مطمئن هستید)



ReleaseDC (hwnd, hdc) ;
DeleteDC (hMemDC) ;

if (hBitMap)
DeleteObject (hBitMap) ;

اگر هم قابل آزاد شدن نیست ، مقدار برگشتی SelectObject ، شئی قبلی انتخاب شده در DC را بر می گرداند که می توانید آن را ذخیره کنید و در پایان دوباره با یک SelectObject قبل از پاک کردن منابع انتخابش کنید تا به حالت اول بر گردد.

ضمنا شما DC مربوط به یک دکمه را باید دریافت کنید و تابع CreateCompatibleDC را برای همان DC فراخوانی کنید که شما NULL قرار داده اید.

najafzade
دوشنبه 06 اسفند 1386, 16:31 عصر
با سلام خدمت تمامی کاربران محترم این تایپیک :

میخواستم بدونم چرا پس از load کردن یک bitmap نمیشه مجددا روی اون bitmap دیگری رو لود کرد ؟

من در برنامه ای نیازدارم bitmap رو به دو صورت زیر بار کنم و هر کدام از این کدها در تابع مربوط به یک دکمه قرار دادم . . . اما چرا پس از یک بار لود شدن bitmap نمیشه مجددا bitmap دیگری لود کرد ؟




CPaintDC dc(this);
HBITMAP hBitMap=(HBITMAP)::LoadBitmap(AfxGetInstanceHandle (),MAKEINTRESOURCE(IDB_BITMAP1));
HDC hMemDC =::CreateCompatibleDC(NULL);
SelectObject(hMemDC,hBitMap);
::StretchBlt(dc.m_hDC,170,70,250,200,hMemDC,0,0,25 0,250,SRCCOPY);//
::DeleteDC(hMemDC);
::DeleteObject(hBitMap);









CPaintDC dc1(this);
HBITMAP hBitMap1=(HBITMAP)::LoadBitmap(AfxGetInstanceHandl e(),MAKEINTRESOURCE(IDB_BITMAP2));
HDC hMemDC1 =::CreateCompatibleDC(NULL);
SelectObject(hMemDC1,hBitMap1);
::StretchBlt(dc1.m_hDC,170,70,250,200,hMemDC1,0,0, 250,250,SRCINVERT);
::DeleteDC(hMemDC1);
::DeleteObject(hBitMap1);


ضمنا پس از ایجاد کامل bitmap چطور میشه اون رو حذف کرد ؟
ممنون میشم منو بی جواب نگذارید

سلام
با اجازه اساتید

شما بایستی محل قرار گیری عکس را Clear کنین.
بعد می تونین عکس جدید رو توش قرار بدین.

با تشکر

A_Salimi
دوشنبه 06 اسفند 1386, 23:54 عصر
فکر میکنم جوابها تا حدی مبهم بودند و من دقیقا متوجه نشدم . . .
اگه ممکنه بیشتر توضیح بدید
سوال رو به این صورت مطرح میکنم :دو تا دکمه دارم که میخوام با کلیک روی هر کدوم یک bitmap لود بشه چرا در عمل با تعاریف ایجاد bitmap پس از لود شدن بیت مپ قادر به لود دیگری نیستیم ؟


ضمنا شما DC مربوط به یک دکمه را باید دریافت کنید و تابع CreateCompatibleDC را برای همان DC فراخوانی کنید که شما NULL قرار داده اید.

منظورتون اینه که باید یک بستر دستگاه حافظه جدید ایجاد بشه ؟


شما بایستی محل قرار گیری عکس را Clear کنین.
بعد می تونین عکس جدید رو توش قرار بدین

چطور میشه این کار رو انجام داد ؟
با تشکر

Nima_NF
سه شنبه 07 اسفند 1386, 00:42 صبح
پاسخ دقیق به این سوال ، نیازمند دانستن اطلاعاتی هست که شما بیان نکرد اید ، عکس ها در کجا نمایش داده می شوند در رویداد OnPaint ، .... قطعه کد کامل تر می توانست بهتر کمک کند؟

ضمنا شما به سبک win32 از توابع استفاده می کنید...

اگر شما در رویداد OnPaint این کار را می کنید ، آنگاه فقط نیاز به یک dc دارید که بعد از آن با یک شرط همیشه باید چک شود کدام دگمه فعل شده است، مثلا اگر دکمه 1 فشار داده شد عکس اول نمایش داده شود و در انتها چون dc برای OnPaint است ، پس قبل از پاکسازی می نویسید:



bmpOld = SelectObject(hMemDC,hBitMap);

// before clean up:
SelectObject(hMemDC,bmpOld);




منظورتون اینه که باید یک بستر دستگاه حافظه جدید ایجاد بشه ؟در مثال شما NULL به DC :



HDC hMemDC =::CreateCompatibleDC( dc );


ضمنا از توابعی مثل InvalidateRect برای refresh تصویر می توانید استفاده کنید.

این لینک را مشاهده کنید: (آخرین نمونه کد)
http://www.functionx.com/visualc/printing/introduction2.htm

A_Salimi
سه شنبه 07 اسفند 1386, 13:13 عصر
عکس ها در کجا نمایش داده می شوند

من سعی کردم به جای استفاده از onpaintخودم یک dc ایجاد کنم و به جای CPaintDC از CClientDC استفاده کنم که اتفاقا خواسته من برطرف شد یعنی با کلیک روی هر دکمه یک bitmap بار میشد اما به یک مشکل بدتر برخوردم . . . مشکل این بود که با قرار گرفتن یک پنجره روی پنجره برنامه من bitmap ها ناپدید می شدند !!!
دلیلش چیه ؟

Nima_NF
سه شنبه 07 اسفند 1386, 21:46 عصر
دستورات گرافیک باید در قسمتی نوشته شود که همراه عمل refresh تصویر در مواقع نیاز انجام شود یعنی مثلا در OnPaint

A_Salimi
چهارشنبه 08 اسفند 1386, 01:13 صبح
مشکل پاک شدن BITMAP رو با قرار دادن کد در ONPAINT برطرف کردم

SMRAH1
چهارشنبه 08 اسفند 1386, 10:05 صبح
سلام
خارج از تابع OnPaint بهتره از کلاس CPaintDC استفاده نکنید و از توابع
GetDC و ReleaseDC که در تمام CWnd ها در دسترسه استفاده کنید.البته باید OnPaintDC رو هم به صورت مناسب تغییر بدهید.
من دوباره کدتونو بازنویسی کردم یعنی :



HDC hDC = ::GetDC(this->m_hWnd);
HBITMAP hBitMap=(HBITMAP)::LoadBitmap(AfxGetInstanceHandle (),MAKEINTRESOURCE(IDB_BITMAP1));
ASSERT(hBitMap);
HDC hMemDC =::CreateCompatibleDC(NULL); SelectObject(hMemDC,hBitMap);
ASSERT(hMemDC);
::StretchBlt(hDC,10,10,58,58,hMemDC,0,0,48,48,SRCC OPY);
::DeleteDC(hMemDC);
::DeleteObject(hBitMap);
::ReleaseDC(this->m_hWnd,hDC);



HDC hDC = ::GetDC(this->m_hWnd);
HBITMAP hBitMap1=(HBITMAP)::LoadBitmap(AfxGetInstanceHandl e(),MAKEINTRESOURCE(IDB_BITMAP1));
HDC hMemDC1 =::CreateCompatibleDC(NULL); SelectObject(hMemDC1,hBitMap1);
::StretchBlt(hDC,10,10,58,58,hMemDC1,0,0,48,48,SRC INVERT);
::DeleteDC(hMemDC1);
::DeleteObject(hBitMap1);
::ReleaseDC(this->m_hWnd,hDC);


موفق باشی

A_Salimi
چهارشنبه 08 اسفند 1386, 15:45 عصر
ممنون از پاسخ شما
روش شما هم دقیقا مثل روش من کار میکنه اما مشکلی رو که من گفتم رو برطرف نکرده و اگه یک پنجره بالای دیالوگ شما قرار بگیره ، Bitmap رو پاک میکنه پس باید در onpaint کدی برای بارکردن bitmap قرار داده شه (البته به نظر من)

A_Salimi
چهارشنبه 08 اسفند 1386, 15:47 عصر
ممنون از پاسخ شما
روش شما هم دقیقا مثل روش من کار میکنه اما مشکلی رو که من گفتم رو برطرف نکرده و اگه یک پنجره بالای دیالوگ شما قرار بگیره ، Bitmap رو پاک میکنه پس باید در onpaint کدی برای بارکردن bitmap قرار داده شه (البته این نظر منه)