עבור לתוכן

בעיית מימוש באפר כפול ב microsoft visual c?

Featured Replies

פורסם

עריכה: הבעיה מוצגת 4 פוסטים למטה.

עיינתי בספר: לימוד visual c++ תוך 21 ימים של SAMS.

בספר (ביום השמיני) יש דרך להצגת להציג תמונה מקובץ שנבחר. קיימים שני חלונות, חלון ראשי שבו בוחרים מה יוצג, וחלון משני שמציג.

אני רוצה לעשות חלון בודד שיציג תמונה שהגדרתי כמשאב. ניסיתי את הקוד הבא, אבל הוא עבד רק כאשר מקמתי אותו בחלון המישני (בתוכנה עם 2 החלונות), ולא הציג את התמונה בתוכנה עם החלון הבודד.


CDialog::OnInitDialog();
...
// TODO: Add extra initialization here
CPaintDC dc(this);
CBitmap bm;

bm.LoadBitmap(IDB_BITMAP);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
dcMem.SelectObject(&bm);
dc.BitBlt(10,10,50,50,&dcMem,0,0,SRCCOPY);
...
}

מה חסר / שגוי בקוד?

לשם השוואה, הינה מימוש הצגת התמונה לפי הספר:

הפונקציה הזו:

void CPaintDlg::OnPaint() 
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CDay8Dlg *pWnd=(CDay8Dlg*)GetParent();
...
ShowBitmap(&dc,pWnd);
...

קוראת לפונקציה הזו:

void CPaintDlg::ShowBitmap(CPaintDC *pdc, CWnd *pWnd)
{
CDay8Dlg *lpWnd =(CDay8Dlg*)pWnd;
BITMAP bm;
lpWnd->m_bmpBitmap.GetBitmap(&bm);
CDC dcMem;

dcMem.CreateCompatibleDC(pdc);
CBitmap* pOldBitmap=(CBitmap*)dcMem.SelectObject(lpWnd->m_bmpBitmap);
CRect lRect;
GetClientRect(lRect);
lRect.NormalizeRect();
pdc->StretchBlt(10,10,(lRect.Width()-20),(lRect.Height()-20),&dcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
}

בתודה לעוזרים,

ערן.

פורסם

האם אתה קורא לOnPaint, או שאתה יוצר חלון חדש ועושה לו domodal ?

פורסם
  • מחבר

בספר יצרו class מסוג דיאלוג ריק (ללא controls)

בפונקציה oninitdialog יצרו את החלון השני ע"י:

m_dlgPaint.Create(IDD_PAINTDLG,this);
m_dlgPaint.ShowWindow(SW_SHOW);

וגורמים לביצוע onpaint ע"י כפתור בחלון הראשון שמבצע:

m_dlgPaint.Invalidate();

אני רוצה חלון ריק בודד שאני אוכל להציב עליו את התמונה, ואח"כ לעדכן את מיקומה (ליצור תנועה)

פורסם
  • מחבר

הצלחתי להציג תמונות רבות, אבל עכשיו יש בעיה של ריצוד (התוכנה מבצעת bitblit לכל תמונה בנפרד)

קראתי שהפיתרון המקובל לבעיה זו הוא באפר כפול (ציור כל התמונות ל DC וירטואלי ואז העברת ה DC הוירטואלי ל DC של החלון),

אך כאשר ניסיתי לממש באפר כפול קיבלתי תמונה מרצדת ורקע החלון הפך לשחור ורואים רק את קווי המתאר של התמונה בלבן.

מה הטעות במימוש שלי?

CPaintDC dc(this);
CBitmap bm;
bm.LoadBitmap(IDB_BITMAP);

CDC BitmapDC;
BitmapDC.CreateCompatibleDC(&dc);
BitmapDC.SelectObject(&bm);

CDC memDC;
memDC.CreateCompatibleDC(&dc);
HBITMAP memBM = CreateCompatibleBitmap (dc, BOARDWIDTH*BLOCKSIZE, BOARDHEIGHT*BLOCKSIZE );
SelectObject ( memDC, memBM );


//paint board
int i,j;
for (i=0;i<BOARDHEIGHT;i++)
for (j=0;j<BOARDWIDTH;j++)
if (board[i][j])
memDC.BitBlt(j*BLOCKSIZE,i*BLOCKSIZE,BLOCKSIZE,BLOCKSIZE,&BitmapDC,0,0,SRCCOPY);

//paint current brick
for (i=0;i<PIECESIZE;i++)
for (j=0;j<PIECESIZE;j++)
if (CurPiece.box[i][j])
memDC.BitBlt(xpos+j*BLOCKSIZE,ypos+i*BLOCKSIZE,BLOCKSIZE,BLOCKSIZE,&BitmapDC,0,0,SRCCOPY);

//copy memDC to dc
dc.BitBlt(0,0,BOARDWIDTH*BLOCKSIZE,BOARDHEIGHT*BLOCKSIZE,&memDC,0,0,SRCCOPY);

במימוש ללא ה DC הוירטואלי [המישמוש המרצד עם הצבעים הנכונים] החלפתי את memDC ב dc ב 2 השורות של BitBlt והורדתי את השורה האחרונה

פורסם

רעיונות גרועים:

GdiFlush();

// Unlock painting
LockUpdate(bLock);

// Flush pending changes, Update will
// also redraw the row.
Update();

פורסם
  • מחבר

אפשר בבקשה קצת יותר לפרט?

אני לא מצליח להבין את הרעיון שלך. הפונקציות הנ"ל לא מוכרות לי, אין שימוש ב bitblit?

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים