65,186
社区成员




void CTextScreen::OnSysCommand(UINT nID, LPARAM lParam)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if( SC_CLOSE == nID)
{
CWnd *pParentWnd = this->GetParent();
this->DestroyWindow();
delete this;
char buf[8] = { 0 };
sprintf(buf,"%d",sizeof(this));
OutputDebugString(buf);
pParentWnd->DestroyWindow();
}
CDialog::OnSysCommand(nID, lParam);
}
p_BtOK->OnDestroy();
delete m_pBtOK;
CTextScreen的PreTranslateMessage(MSG* pMsg)中有消息的路由
HWND hWnd = NULL;
if( pMsg->message == WM_LBUTTONDBLCLK)
{
if( pMsg->hwnd == ( hWnd = ::GetDlgItem(m_hWnd,IDB_BT_NEW_SCREEN_OK) ) )
{
MessageBox("NewOK"); //实际上是pCurScreen->HandleMsg(KEY_XX);
}
else if( pMsg->hwnd ==(hWnd = ::GetDlgItem(m_hWnd,IDB_BT_NEW_SCREEN_CANCEL) ) )
{
MessageBox("NewCancel"); //实际上是pCurScreen->HandleMsg(KEY_XX);
}
}
int CzButton::GetBitmapWidth (HBITMAP hBitmap)
{
BITMAP bm; GetObject(hBitmap,sizeof(BITMAP),(PSTR)&bm);
return bm.bmWidth;
}
int CzButton::GetBitmapHeight (HBITMAP hBitmap)
{
BITMAP bm; GetObject(hBitmap,sizeof(BITMAP),(PSTR)&bm);
return bm.bmHeight;
}
/////////////////////////////////////////////////////////////////////////////
void CzButton::SetSkin(UINT normal,UINT down,UINT over,UINT disabled, UINT focus,UINT mask,
short drawmode, short border, short margin)
{
m_bNormal.DeleteObject(); //free previous allocated bitmap
m_bDown.DeleteObject();
m_bOver.DeleteObject();
m_bDisabled.DeleteObject();
m_bMask.DeleteObject();
m_bFocus.DeleteObject();
if (normal>0) m_bNormal.LoadBitmap(normal);
if (down>0) m_bDown.LoadBitmap(down);
if (over>0) m_bOver.LoadBitmap(over);
if (focus>0) m_bFocus.LoadBitmap(focus);
if (disabled>0) m_bDisabled.LoadBitmap(disabled);
else if (normal>0) m_bDisabled.LoadBitmap(normal);
m_DrawMode=max(0,min(drawmode,2));
m_Border=border;
m_FocusRectMargin=max(0,margin);
if (mask>0){
m_bMask.LoadBitmap(mask);
if (hClipRgn) DeleteObject(hClipRgn);
hClipRgn = CreateRgnFromBitmap(m_bMask,RGB(255,255,255));
if (hClipRgn){
SetWindowRgn(hClipRgn, TRUE);
SelectClipRgn((HDC)GetDC(),hClipRgn);
}
if (m_DrawMode==0){
SetWindowPos(NULL,0,0,GetBitmapWidth(m_bMask),
GetBitmapHeight(m_bMask),SWP_NOZORDER|SWP_NOMOVE);
}
}
}
////////////////////////////////////////////////////////////////////////////
void CzButton::SetPosition(CRect RC, int pos)
{
MoveWindow(RC.left + 50 + 40 * pos, RC.bottom - 30, 30, 20);
}
/////////////////////////////////////////////////////////////////////////////
HRGN CzButton::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color)
{
if (!hBmp) return NULL;
BITMAP bm;
GetObject( hBmp, sizeof(BITMAP), &bm ); // get bitmap attributes
CDC dcBmp;
dcBmp.CreateCompatibleDC(GetDC()); //Creates a memory device context for the bitmap
dcBmp.SelectObject(hBmp); //selects the bitmap in the device context
const DWORD RDHDR = sizeof(RGNDATAHEADER);
const DWORD MAXBUF = 40; // size of one block in RECTs
// (i.e. MAXBUF*sizeof(RECT) in bytes)
LPRECT pRects;
DWORD cBlocks = 0; // number of allocated blocks
INT i, j; // current position in mask image
INT first = 0; // left position of current scan line
// where mask was found
bool wasfirst = false; // set when if mask was found in current scan line
bool ismask; // set when current color is mask color
// allocate memory for region data
RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RDHDR;
pRgnData->iType = RDH_RECTANGLES;
pRgnData->nCount = 0;
for ( i = 0; i < bm.bmHeight; i++ )
for ( j = 0; j < bm.bmWidth; j++ ){
// get color
ismask=(dcBmp.GetPixel(j,bm.bmHeight-i-1)!=color);
// place part of scan line as RECT region if transparent color found after mask color or
// mask color found at the end of mask image
if (wasfirst && ((ismask && (j==(bm.bmWidth-1)))||(ismask ^ (j<bm.bmWidth)))){
// get offset to RECT array if RGNDATA buffer
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, bm.bmHeight - i - 1, j+(j==(bm.bmWidth-1)), bm.bmHeight - i );
// if buffer full reallocate it
if ( pRgnData->nCount >= cBlocks * MAXBUF ){
LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) );
delete pRgnData;
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
}
wasfirst = false;
} else if ( !wasfirst && ismask ){ // set wasfirst when mask is found
first = j;
wasfirst = true;
}
}
dcBmp.DeleteDC(); //release the bitmap
// create region
/* Under WinNT the ExtCreateRegion returns NULL (by Fable@aramszu.net) */
// HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
/* ExtCreateRegion replacement { */
HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
ASSERT( hRgn!=NULL );
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
for(i=0;i<(int)pRgnData->nCount;i++)
{
HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
if (hr) DeleteObject(hr);
}
ASSERT( hRgn!=NULL );
/* } ExtCreateRegion replacement */
delete pRgnData;
return hRgn;
}
/////////////////////////////////////////////////////////////////////////////
COLORREF CzButton::SetTextColor(COLORREF new_color)
{
COLORREF tmp_color=m_TextColor;
m_TextColor=new_color;
return tmp_color; //returns the previous color
}
有关pTextScreen;
extern CTextScreen *pTextScreen; //class CTextScreen:public CDialog()
然后我在一个类如
CScreenTaskManage构造函数中
m_pBtDown = new CzButton();
m_pBtDown->Create(NULL,WS_CHILD |WS_VISIBLE|BS_PUSHBUTTON,rcBt,pTextScreen,IDB_BT_TASK_N_DOWN );
m_pBtDown->SetSkin(PIC_SYS_INFO_CONFIRM_U,PIC_SYS_INFO_CONFIRM_D,0,0,0,0,0,0,0);
m_pBtDown->MoveWindow(xPos,yPos,nWidth,nHeight);
能够正常显示并响应消息
但是我析构函数中调用 delete m_pBtDown;可以返回到另一个画面,但是会断点在
assert(::IsWindow(m_hWnd)); //这里 有时候m_hWnd明明是被delete掉了为0,
在调试的时候又变成开始的值,我猜可能是堆栈被破坏了,但是一直没找出哪里错了,
最有可能出错的地方是 CzButton 中 对hClipRgn的操作,苦于一直没找出错误,现求肋于兄弟们,
先谢过拉!