Здравствуйте. У меня такая проблема: в MFC приложении мне понадобилось создавать вручную диалоговое окно, здесь на форуме я отыскал, как это сделать на WinAPI, вот код:
#define ID_PRINT_MESSAGE 1003
struct BlockParams {
int baud_rate;
int block_address;
bool is_bmp_resource;
char* bmp_path;
UINT bmp_res_id;
COLORREF jumper_color;
};
struct DIALOG
{
DLGTEMPLATE dlgTemplate;
WORD wMenu;
WORD wClass;
WCHAR szTitle[9];
WORD wFontSize;
WCHAR szFontFaceName[7];
DLGITEMTEMPLATE ctrlButtonOk;
WORD wClassBO;
WORD wClassBOId;
WCHAR szTitleBO[3];
WORD wDataBO;
WORD wAlign3;
DLGITEMTEMPLATE ctrlButtonMdg;
WORD wClassBM;
WORD wClassBMId;
WCHAR szTitleBM[9];
WORD wDataBM;
};
DIALOG dialog =
{
{
WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_CENTER | DS_SETFONT,
0,
2,
0, 0, 400, 320,
},
0x0000,
0x0000,
{ L'I', L'm', L'a', L'g', L'e', L' ', L' ', L' ', L'\0' },
8,
{ L'T', L'a', L'h', L'o', L'm', L'a', L'\0' },
{
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | WS_GROUP | BS_DEFPUSHBUTTON,
0,
340, 290, 50, 14, IDOK,
},
0xFFFF,
0x0080,
{ L'O', L'K', L'\0' },
0,
0,
{
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | BS_PUSHBUTTON,
0,
270, 290, 50, 14, ID_PRINT_MESSAGE,
},
0xFFFF,
0x0080,
{ L'&', L'P', L'r', L'i', L'n', L't', L'', L'', L'\0' },
0,
};
void drawImage(int baudRate, CDC& targetDC, CDC& bmpDC, BITMAP& bmpInfo, UINT resourceID, char* bmpPath, bool isBMPResource = true){
/*
* baud rates constants:
* 1 - 125Kbt/sec
* 2 - 250Kbt/sec
* 3 - 500Kbt/sec
* 4 - 1000Kbt/sec
*/
CBitmap bmp;
COLORREF color = RGB(255,255,255);
CPen pen;
CBrush brush;
BOOL isBMPLoaded = FALSE;
if(isBMPResource){
isBMPLoaded = bmp.LoadBitmap(resourceID);
} else {
isBMPLoaded = bmp.Attach(LoadImage(0, bmpPath, IMAGE_BITMAP, 0,0,LR_LOADFROMFILE));
}
if(isBMPLoaded){
bmpDC.DeleteDC ();
// Get the size of the bitmap
bmp.GetBitmap(&bmpInfo);
// Create an in-memory DC compatible with the
// display DC we're using to paint
bmpDC.CreateCompatibleDC(&targetDC);
bmpDC.SetBkMode(TRANSPARENT);
// Select the bitmap into the in-memory DC
CBitmap* pOldBitmap = bmpDC.SelectObject(&bmp);
// Select the bitmap into the in-memory DC
pen.DeleteObject();
pen.CreatePen(PS_SOLID, 1, color);
brush.DeleteObject();
brush.CreateSolidBrush(color);
bmpDC.SelectObject(&pen);
bmpDC.SetTextColor(color);
if(baudRate==1){//125Kbt/sec
} else if (baudRate==2){//250Kbt/sec
CRect jumperRect(388, 410, 413, 420);
bmpDC.FillRect(&jumperRect, &brush);
} else if (baudRate==3){//500Kbt/sec
CRect jumperRect(388, 396, 413, 406);
bmpDC.FillRect(&jumperRect, &brush);
} else if (baudRate==4){//1000Kbt/sec
CRect jumperRect0(388, 410, 413, 420);
bmpDC.FrameRect(&jumperRect0, &brush);
CRect jumperRect1(388, 396, 413, 406);
bmpDC.FrameRect(&jumperRect1, &brush);
}
bmp.Detach();
} else {
}
}
int CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
if (IDOK == LOWORD(wParam) || IDCANCEL == LOWORD(wParam))
{
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
if (ID_PRINT_MESSAGE == LOWORD(wParam))
{
MessageBox(hwndDlg, TEXT("This is simple message box."), TEXT("Message Box"), MB_OK | MB_ICONINFORMATION);
return TRUE;
}
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwndDlg, &ps);
CDC dc;
dc.Attach(hdc);
CDC bmpDC;
BITMAP bmpInfo;
//тут я загружаю картинку и рисую на ней в совместимом контексте
drawImage(4, dc, bmpDC, bmpInfo, 0, "Block1.bmp", false);
dc.BitBlt(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, &bmpDC, 0, 0, SRCCOPY);
EndPaint(hwndDlg, &ps);
return FALSE;
}
return FALSE;
}
По началу, когда этот диалог появляется, на нем все рисуется. Потом я беру какое-то другое окно и начинаю "возить" им поверх своего диалога — какое-то время все нормально перерисовывается, но спустя пару секунд верхнее окно затирает картинку на диалоге, она перестает перерисовываться. Я искал ответ в форуме, но подобной проблемы не встретил ни у кого. Буду благодарен за любые идеи.