文档章节

MFC边框重绘

江河海流
 江河海流
发布于 2016/01/30 17:04
字数 2997
阅读 514
收藏 2
点赞 1
评论 0

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#pragma once
 
#include "DUIButton.h"
#include <map>
usingnamespacestd;
 
/*
框架窗口非客户区自绘类
供大家学习参考
*/
 
 
// CSkinFrameWnd frame
 
classCSkinFrameWnd :publicCFrameWndEx
{
    DECLARE_DYNCREATE(CSkinFrameWnd)
protected:
    CSkinFrameWnd();          // protected constructor used by dynamic creation
    virtual~CSkinFrameWnd();
     CDUIButton* AddTitleButton(LPRECT lpRect, Image *pImage,UINTnCount = 3 ,UINTnID = 0,LPCTSTRlpszCaption=NULL);
protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msgvoidOnNcPaint();
    afx_msgvoidOnNcCalcSize(BOOLbCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
    afx_msgLRESULTOnNcHitTest(CPoint point);
    afx_msgvoidOnGetMinMaxInfo(MINMAXINFO* lpMMI);
    afx_msgBOOLOnNcActivate(BOOLbActive);
    afx_msgvoidOnActivate(UINTnState, CWnd* pWndOther,BOOLbMinimized);
    afx_msgvoidOnNcLButtonDblClk(UINTnHitTest, CPoint point);
    afx_msgvoidOnNcLButtonDown(UINTnHitTest, CPoint point);
    afx_msgvoidOnNcLButtonUp(UINTnHitTest, CPoint point);
    afx_msgvoidOnNcMouseMove(UINTnHitTest, CPoint point);
    afx_msgvoidOnNcMouseHover(UINTnFlags, CPoint point);
    afx_msgvoidOnNcMouseLeave();
    afx_msgvoidOnSize(UINTnType,intcx,intcy);
    afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);
    afx_msgBOOLOnNcCreate(LPCREATESTRUCT lpCreateStruct);
protected:
    virtualLRESULTWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam);
     int      TButtonHitTest(CPoint point, CRect& rtButton);
protected:
    int m_nTitleHeight;
    int m_nFrameWidth;
    Image *m_pBkImage;
    //标题按钮列表
    std::map<int,CDUIButton> m_TitleBtn;
    int   m_iXButtonHovering;
    BOOL  m_bNCHovering;
    BOOL  m_bNCTracking;
    CRgn m_Rgn;
    //三个标题按钮图片
    vector<Image*> m_WindowBtnImage;
    CRect  m_rcIcon;
};

[2].[代码] CSkinFrameWnd cpp 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
#include "stdafx.h"
#include "SkinFrameWnd.h"
 
#define  ID_CLOSE_BTN 110
#define  ID_MAX_BTN   111
#define  ID_MIN_BTN   112
 
// CSkinFrameWnd
 
IMPLEMENT_DYNCREATE(CSkinFrameWnd,CFrameWndEx)
 
CSkinFrameWnd::CSkinFrameWnd()
{
    m_nTitleHeight = 38;
    m_nFrameWidth = 3;
 
    Image *pImage = CSkinManager::GetInstance()->GetSkinItem(_T("dialog\\dlg_minimize_button.bmp"));
    m_WindowBtnImage.push_back(pImage);
 
    pImage = CSkinManager::GetInstance()->GetSkinItem(_T("dialog\\dlg_maxmize_button.bmp"));
    m_WindowBtnImage.push_back(pImage);
 
    pImage = CSkinManager::GetInstance()->GetSkinItem(_T("dialog\\dlg_close_btn.bmp"));
    m_WindowBtnImage.push_back(pImage);
 
    m_pBkImage = CSkinManager::GetInstance()->GetSkinItem(_T("dialog\\DialogBkg.png"));
 
    m_iXButtonHovering = -1;
 
    m_bNCHovering = FALSE;
    m_bNCTracking = FALSE;
 
    m_rcIcon = CRect(15,13,15+GetSystemMetrics(SM_CXSMICON),13+GetSystemMetrics(SM_CYSMICON));
 
}
 
CSkinFrameWnd::~CSkinFrameWnd()
{
}
 
 
BEGIN_MESSAGE_MAP(CSkinFrameWnd, CFrameWndEx)
    ON_WM_NCPAINT()
    ON_WM_NCCALCSIZE()
    ON_WM_NCHITTEST()
    ON_WM_GETMINMAXINFO()
    ON_WM_NCACTIVATE()
    ON_WM_ACTIVATE()
    ON_WM_NCLBUTTONDBLCLK()
    ON_WM_NCLBUTTONDOWN()
    ON_WM_NCLBUTTONUP()
    ON_WM_NCMOUSEMOVE()
    ON_WM_NCMOUSEHOVER()
    ON_WM_NCMOUSELEAVE()
    ON_WM_SIZE()
    ON_WM_SYSCOMMAND()
    ON_WM_NCCREATE()
END_MESSAGE_MAP()
 
 
// CSkinFrameWnd message handlers
 
voidCSkinFrameWnd::OnNcPaint()
{
    CWindowDC dc(this);
 
    if(m_pBkImage==NULL)
    {
        return;
    }
 
    CDC MemDC;
 
    // 获取位置
    CRect rcWindow;
    GetWindowRect(&rcWindow);
    rcWindow.OffsetRect( -rcWindow.left, -rcWindow.top);
 
 
    CRect rcClient;
    GetClientRect(&rcClient);
 
    //剪除掉客户区
    rcClient.OffsetRect(m_nFrameWidth, m_nTitleHeight);
    dc.ExcludeClipRect(rcClient.left, rcClient.top,
        rcClient.right, rcClient.bottom);
 
 
    MemDC.CreateCompatibleDC(&dc);
 
 
    CBitmap bmp;
    bmp.CreateCompatibleBitmap(&dc,rcWindow.Width(),rcWindow.Height());
    MemDC.SelectObject(&bmp);
    MemDC.SetBkMode(TRANSPARENT);
 
    Gdiplus::Graphics graphics(MemDC.GetSafeHdc());
    RectF destRect;
 
    //绘制底部和边框
    destRect.X = 0;
    destRect.Y = rcWindow.Height() - m_nFrameWidth;
    destRect.Width = rcWindow.Width();
    destRect.Height = m_nFrameWidth;
    graphics.DrawImage(m_pBkImage,destRect,m_nTitleHeight,m_pBkImage->GetHeight()-m_nFrameWidth,m_nFrameWidth,m_nFrameWidth,UnitPixel);
 
    destRect.X = rcWindow.right-m_nTitleHeight;
    destRect.Y = rcWindow.bottom - m_nTitleHeight;
    destRect.Width = m_nTitleHeight;
    destRect.Height = m_nTitleHeight;
    graphics.DrawImage(m_pBkImage,destRect,m_pBkImage->GetWidth()-m_nTitleHeight,m_pBkImage->GetHeight()-m_nTitleHeight,m_nTitleHeight,m_nTitleHeight,UnitPixel);
 
    destRect.X = 0;
    destRect.Y = rcWindow.Height() - m_nTitleHeight;
    destRect.Width = m_nTitleHeight;
    destRect.Height = m_nTitleHeight;
    graphics.DrawImage(m_pBkImage,destRect,0,m_pBkImage->GetHeight()-m_nTitleHeight,m_nTitleHeight,m_nTitleHeight,UnitPixel);
 
    //左边框
    destRect.X = 0;
    destRect.Y = m_nTitleHeight;
    destRect.Width = m_nFrameWidth;
    destRect.Height = rcWindow.Height() - 2*m_nTitleHeight;
    graphics.DrawImage(m_pBkImage,destRect,0,m_nTitleHeight,m_nFrameWidth,m_nFrameWidth,UnitPixel);
 
 
    //右边框
    destRect.X = rcWindow.Width() - m_nFrameWidth;
    destRect.Y = m_nTitleHeight;
    destRect.Width = m_nFrameWidth;
    destRect.Height = rcWindow.Height() - 2*m_nTitleHeight;
    graphics.DrawImage(m_pBkImage,destRect,m_pBkImage->GetWidth()-m_nFrameWidth,m_nTitleHeight,m_nFrameWidth,m_nFrameWidth,UnitPixel);
 
    //绘制标题栏
    destRect.X = 0;
    destRect.Y = 0;
    destRect.Width = rcWindow.Width();
    destRect.Height = m_nTitleHeight;
    graphics.DrawImage(m_pBkImage,destRect,50,0,5,m_nTitleHeight,UnitPixel);
    graphics.DrawImage(m_pBkImage,0,0,0,0,50,m_nTitleHeight,UnitPixel);
    graphics.DrawImage(m_pBkImage,rcWindow.Width() - 50,0,m_pBkImage->GetWidth()-50,0,50,m_nTitleHeight,UnitPixel);
 
 
    intxPos = 15;
    intyPos = 15;
 
    HICONhIcon = GetIcon(FALSE);
    if(hIcon)
    {
        DrawIconEx(MemDC,xPos, yPos-2,hIcon,GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
 
        xPos += GetSystemMetrics(SM_CXSMICON);
        xPos += 5;
    }
 
    CString strText;
    GetWindowText(strText);
    if(!strText.IsEmpty())
    {
        //绘制标题
        LOGFONT lfFont;
        memset(&lfFont, 0,sizeof(lfFont));
        lfFont.lfHeight = -12;
        lfFont.lfWeight |= FW_BOLD;
        lstrcpy(lfFont.lfFaceName, _T("宋体"));
        Gdiplus::Font font(dc.GetSafeHdc(), &lfFont);
 
        StringFormat stringFormat;
        stringFormat.SetFormatFlags( StringFormatFlagsNoWrap);
        stringFormat.SetAlignment(StringAlignmentNear);
        stringFormat.SetLineAlignment(StringAlignmentNear);
        CStringW strTitle(strText);
        SolidBrush brush((ARGB)Color::White);
        PointF point;
 
        point.X=(Gdiplus::REAL)xPos;
        point.Y=(Gdiplus::REAL)yPos;
        graphics.DrawString(strTitle, strTitle.GetLength(), &font, point,&stringFormat, &brush);
 
    }
 
    CRect rcPaint;
    dc.GetClipBox(&rcPaint);
    std::map<int,CDUIButton>::iterator iter;
    for(iter = m_TitleBtn.begin(); iter != m_TitleBtn.end(); iter++)
    {
        CDUIButton& dcControl = iter->second;
        CRect rcControl;
        dcControl.GetRect(&rcControl);
 
        // 判断当前按钮是否需要重绘
        if(!rcPaint.IsRectEmpty() && !CRect().IntersectRect(&rcControl, rcPaint))
        {
            continue;
        }
 
        dcControl.DrawButton(graphics);
    }
 
 
 
    dc.BitBlt(0,0,rcWindow.Width(),rcWindow.Height(),&MemDC,0,0,SRCCOPY);
 
    dc.SelectClipRgn(NULL);
}
 
voidCSkinFrameWnd::OnNcCalcSize(BOOLbCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
    if(bCalcValidRects)  
    {  
 
        CRect& rc = (CRect&)lpncsp->rgrc[0];//get the client rectangle  
        rc.top += m_nTitleHeight;  
        rc.left += m_nFrameWidth;  
        rc.bottom -= m_nFrameWidth;  
        rc.right -= m_nFrameWidth;  
 
    }
}
 
LRESULTCSkinFrameWnd::OnNcHitTest(CPoint point)
{
    CRect rtButton;
    CRect rcWindow;
    GetWindowRect(&rcWindow);
    CPoint pt = point;
    pt.x -=rcWindow.left;
    pt.y -= rcWindow.top;
 
    intiButton = TButtonHitTest(pt, rtButton);
    if(iButton != -1)
    {
        switch(iButton)
        {
        caseID_CLOSE_BTN:
            {
                returnHTCLOSE;
            }
            break;
        caseID_MAX_BTN:
            {
 
                returnHTMAXBUTTON;
            }
            break;
        caseID_MIN_BTN:
            {
                returnHTMINBUTTON;
            }
            break;
        }
    }
    elseif(m_rcIcon.PtInRect(pt))
    {
        returnHTSYSMENU;
    }
 
    returnCFrameWndEx::OnNcHitTest(point);
}
 
voidCSkinFrameWnd::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
     lpMMI->ptMinTrackSize.y = m_nTitleHeight + m_nFrameWidth;
    CFrameWnd::OnGetMinMaxInfo(lpMMI);
}
 
BOOLCSkinFrameWnd::OnNcActivate(BOOLbActive)
{
     OnNcPaint();
     returnTRUE;
}
 
voidCSkinFrameWnd::OnActivate(UINTnState, CWnd* pWndOther,BOOLbMinimized)
{
    CFrameWndEx::OnActivate(nState, pWndOther, bMinimized);
 
    OnNcPaint();
}
 
voidCSkinFrameWnd::OnNcLButtonDblClk(UINTnHitTest, CPoint point)
{
    CRect rcWindow;
    GetWindowRect(&rcWindow);
    rcWindow.bottom = rcWindow.top + m_nTitleHeight;
 
 
    CPoint pt = point;
    CRect rtButton;
    intiButton = TButtonHitTest(pt, rtButton);
    if(iButton != -1)
    {
        m_TitleBtn[iButton].LButtonDown();
        OnNcPaint();
        return;
    }
 
    if(rcWindow.PtInRect(pt))
    {
        if(IsZoomed())
        {
            ShowWindow(SW_RESTORE);
        }
        else
        {
            ShowWindow(SW_MAXIMIZE);
        }
 
        OnNcPaint();
        return;
    }
 
    OnNcPaint();
}
 
voidCSkinFrameWnd::OnNcLButtonDown(UINTnHitTest, CPoint point)
{
    CRect rtButton;
    CRect rcWindow;
    GetWindowRect(&rcWindow);
    CPoint pt = point;
    pt.x -=rcWindow.left;
    pt.y -= rcWindow.top;
 
    intiButton = TButtonHitTest(pt, rtButton);
    if(iButton != -1)
    {
        m_TitleBtn[iButton].LButtonDown();
        OnNcPaint();
        return;
    }
     
     
    if(m_rcIcon.PtInRect(pt))
    {
        CMenu *pSysMenu = GetSystemMenu(FALSE);
        if(pSysMenu)
        {
            pSysMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y,this, NULL);
        }
        return;
    }
    elseif(nHitTest >= HTLEFT && nHitTest <= HTBOTTOMRIGHT || nHitTest == HTCAPTION)
    {      
        CFrameWnd::OnNcLButtonDown(nHitTest, point);
        return;
    }
 
 
 
 
    CFrameWndEx::OnNcLButtonDown(nHitTest, point);
}
 
voidCSkinFrameWnd::OnNcLButtonUp(UINTnHitTest, CPoint point)
{
    CRect rtButton;
    CRect rcWindow;
    GetWindowRect(&rcWindow);
    CPoint pt = point;
    pt.x -=rcWindow.left;
    pt.y -= rcWindow.top;
 
    intiButton = TButtonHitTest(pt, rtButton);
    if(iButton != -1)
    {
        switch(iButton)
        {
        caseID_CLOSE_BTN:
            {
                SendMessage(WM_SYSCOMMAND,SC_CLOSE,0);
            }
            break;
        caseID_MAX_BTN:
            {
                if(IsZoomed())
                {
                    SendMessage(WM_SYSCOMMAND,SC_RESTORE,0);
                }
                else
                {
                    SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);
                }
            }
            break;
        caseID_MIN_BTN:
            {
                SendMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);
            }
            break;
        default:
            {
               m_TitleBtn[iButton].LButtonUp();
               OnNcPaint();
            }
            break;
        }
    }
    else
    {
        CFrameWndEx::OnNcLButtonUp(nHitTest, point);
    }
}
 
 
voidCSkinFrameWnd::OnNcMouseMove(UINTnHitTest, CPoint point)
{
    if(!m_bNCTracking)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize =sizeof(tme);
        tme.hwndTrack = m_hWnd;
        tme.dwFlags = TME_NONCLIENT;
        tme.dwHoverTime = 1;
        m_bNCTracking = _TrackMouseEvent(&tme);
    }
 
    if(nHitTest>=HTLEFT && nHitTest <= HTBOTTOMRIGHT ||
        nHitTest == HTCAPTION)
    {
        CFrameWnd::OnNcMouseMove(nHitTest, point);
 
    }
 
    CRect rtButton;
    CRect rcWindow;
    GetWindowRect(&rcWindow);
    point.x -=rcWindow.left;
    point.y -= rcWindow.top;
    intiButton = TButtonHitTest(point, rtButton);
    if(iButton != m_iXButtonHovering)
    {
        if(m_iXButtonHovering != -1)
        {
            m_TitleBtn[m_iXButtonHovering].MouseLeave();
            m_iXButtonHovering = -1;
        }
        if(iButton != -1)
        {
            m_iXButtonHovering = iButton;
            m_TitleBtn[m_iXButtonHovering].MouseHover();
        }
 
        OnNcPaint();
    }
}
 
voidCSkinFrameWnd::OnNcMouseHover(UINTnFlags, CPoint point)
{
    m_bNCHovering = TRUE;
    //CFrameWndEx::OnNcMouseHover(nFlags, point);
}
 
voidCSkinFrameWnd::OnNcMouseLeave()
{
    m_bNCTracking = FALSE;
    m_bNCHovering = FALSE;
 
    if(m_iXButtonHovering != -1)
    {
        m_TitleBtn[m_iXButtonHovering].MouseLeave();
        m_iXButtonHovering = -1;
    }
 
    //CFrameWndEx::OnNcMouseLeave();
}
 
voidCSkinFrameWnd::OnSize(UINTnType,intcx,intcy)
{
    CFrameWndEx::OnSize(nType, cx, cy);
 
    if(nType != SIZE_MINIMIZED && nType != SIZE_MAXHIDE )
    {
        if(m_Rgn.GetSafeHandle())
        {
            m_Rgn.DeleteObject();
        }
 
        CRect rc;
        GetWindowRect(&rc);//获得窗口矩形
        rc -= rc.TopLeft();
        m_Rgn.CreateRoundRectRgn(rc.left, rc.top,   rc.right+1, rc.bottom+1, 5, 5);//根据窗口矩形创建一个圆角矩形
        SetWindowRgn(m_Rgn, TRUE);//根据圆角矩形指定的区域改变窗口的形状
    }
 
    CRect rcWnd;
    GetWindowRect(&rcWnd);
    rcWnd.OffsetRect( -rcWnd.left, -rcWnd.top);
 
    CRect rMin(rcWnd.right - 74, 8, rcWnd.right-54, 30);
    m_TitleBtn[ID_MIN_BTN].SetRect(rMin);
    CRect rMax(rcWnd.right - 52, 8, rcWnd.right-32, 30);
    m_TitleBtn[ID_MAX_BTN].SetRect(rMax);
    CRect rClose(rcWnd.right - 30, 8, rcWnd.right - 10, 30);
    m_TitleBtn[ID_CLOSE_BTN].SetRect(rClose);
 
    if(nType == SIZE_MAXIMIZED||
        nType == SIZE_RESTORED)
    {
        OnNcPaint();
    }
 
}
 
voidCSkinFrameWnd::OnSysCommand(UINTnID,LPARAMlParam)
{
    if(nID != SC_CLOSE)
    {
        OnNcPaint();
    }
 
    CFrameWndEx::OnSysCommand(nID, lParam);
}
 
LRESULTCSkinFrameWnd::WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)
{
    if(message == 0x125)
    {
        OnNcPaint();
    }
 
    if(message ==0x00AE||//WM_NCUAHDRAWCAPTION
        message==0x00AF)//WM_NCUAHDRAWFRAME)
    {
        OnNcPaint();
        return0;
    }
 
    returnCFrameWndEx::WindowProc(message, wParam, lParam);
}
 
BOOLCSkinFrameWnd::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
{
    if(!CFrameWndEx::OnNcCreate(lpCreateStruct))
        returnFALSE;
 
    CRect rcWnd;
    GetWindowRect(&rcWnd);
    rcWnd.OffsetRect( -rcWnd.left, -rcWnd.top);
 
    CRect rcControl;
    rcControl.left = rcWnd.right- 35;
    rcControl.top = 5;
    rcControl.right = rcControl.left + 20;
    rcControl.bottom = rcControl.top + 20;
    AddTitleButton(rcControl,m_WindowBtnImage[2],3,ID_CLOSE_BTN);
 
    AddTitleButton(rcControl,m_WindowBtnImage[1],3,ID_MAX_BTN);
 
    AddTitleButton(rcControl,m_WindowBtnImage[0],3,ID_MIN_BTN);
 
 
    returnTRUE;
}
 
//往对话框添加一个按钮
CDUIButton* CSkinFrameWnd::AddTitleButton(LPRECT lpRect, Image *pImage,UINTnCount/*= 3*/,UINTnID/* = 0*/,LPCTSTRlpszCaption/*=NULL*/)
{
    CDUIButton dcControl;
    dcControl.CreateButton(lpszCaption, lpRect,this,pImage,nCount, nID);
    m_TitleBtn[nID] = dcControl;
 
    return&m_TitleBtn[nID];
}
 
intCSkinFrameWnd::TButtonHitTest(CPoint point, CRect& rtButton)
{
    std::map<int,CDUIButton>::iterator iter;
    for(iter = m_TitleBtn.begin(); iter != m_TitleBtn.end(); iter++)
    {
        CDUIButton& dcControl = iter->second;
        if(dcControl.PtInButton(point))
        {
            dcControl.GetRect(&rtButton);
            returndcControl.GetControlId();
        }
    }
    return-1;
}

[3].[代码] CDUIButton h(Gui绘制) 跳至 [1] [2] [3] [4] [5] [6]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once
 
#include <GdiPlus.h>
usingnamespaceGdiplus;
 
classCDUIButton
{
public:
    // 标准构造函数
    CDUIButton()
    {
        m_bCheck = FALSE;
        m_bHovering = FALSE;
        m_bPressed = FALSE;
        m_bDisabled = FALSE;
        m_pIcon = NULL;
        m_pParent = NULL;
    }
 
    virtual~CDUIButton(){}
 
    // 设置按钮矩形位置
    voidSetRect(LPCRECT lpRect);
    // 获取按钮矩形位置
    voidGetRect(LPRECT lpRect){*lpRect = *m_rcRect;}
    // 检测指定点是否处于按钮内
    BOOLPtInButton(CPoint& point){returnm_rcRect.PtInRect(point);}
    // 绘制按钮
    virtualvoidDrawButton( Gdiplus::Graphics&  graphics);
    // 创建按钮
    voidCreateButton(LPCTSTRlpszCaption,LPRECT lpRect,CWnd* pParent, Image* pImage,UINTnCount = 4,UINTnID = 0);
    //设置按钮图标信息
    void SetIconInfo(Image *pIcon,CPoint ptPos = CPoint(5,3),BOOLbRedraw=FALSE);
    // 设置按钮状态
    voidEnableButton(BOOLbEnable)
    {
        m_bDisabled = !bEnable;
        m_pParent->InvalidateRect(m_rcRect);
    }
 
    // 设置按钮选定状态
    voidSetCheck(BOOLbCheck)
    {
        m_bCheck = bCheck;
        m_pParent->InvalidateRect(m_rcRect);
    }
    // 获取按钮Id
    UINTGetControlId(){returnm_nID;};
    // 触发按钮事件
    voidDoCommand()
    {
        if(!m_bDisabled)
        {
            m_bCheck = !m_bCheck;
            m_pParent->InvalidateRect(m_rcRect);
            m_pParent->PostMessage(WM_COMMAND, m_nID);
        }
    }
 
    // 鼠标按下按钮事件
    voidLButtonDown()
    {
        if(!m_bDisabled)
        {
            m_bPressed = TRUE;
            m_pParent->InvalidateRect(m_rcRect);
        }
    };
    // 鼠标放下按钮事件
    voidLButtonUp()
    {
        if(!m_bDisabled)
        {
            if(m_bPressed == TRUE)
            {
                m_bCheck = !m_bCheck;
                m_bPressed = FALSE;
                m_pParent->InvalidateRect(m_rcRect);
                m_pParent->PostMessage(WM_COMMAND, m_nID);
            }
        }
    }
    // 鼠标进入按钮区域事件
    voidMouseHover()
    {
        if(!m_bDisabled)
        {
            m_bHovering = TRUE;
            m_pParent->InvalidateRect(m_rcRect);
        }
    }
    // 鼠标离开按钮区域事件
    voidMouseLeave()
    {
        if(!m_bDisabled)
        {
            m_bPressed = FALSE;
            m_bHovering = FALSE;
            m_pParent->InvalidateRect(m_rcRect);
        }
    }
 
protected:
    // 按钮矩形位置
    CRect   m_rcRect;
    // 标识鼠标进入按钮区域
    BOOL   m_bHovering;
    // 标识已经点击按钮
    BOOL   m_bPressed;
    // 标识按钮已经被禁用
    BOOL   m_bDisabled;
    // 标识按钮已经被选中
    BOOL   m_bCheck;
    // 按钮图片
    Image *m_pImage;
    // 按钮图片中包含的图片个数
    UINT   m_nImageCount;
 
    //图标(一个按钮可以给它设置一个小图标)
    Image *m_pIcon;
    //图标左上角位置
    CPoint m_ptIcon;
 
    // 按钮Id号
    int    m_nID;
    // 按钮父窗口
    CWnd*   m_pParent;
    //按钮标题文本
    CString m_strCaption;
};

[4].[代码] CDUIButton Cpp 跳至 [1] [2] [3] [4] [5] [6]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "StdAfx.h"
#include "DUIButton.h"
 
 
// 绘制按钮
voidCDUIButton::DrawButton( Gdiplus::Graphics&  graphics)
{
    // 获取按钮图片信息
    UINTiCount = m_nImageCount;
    intiButtonIndex = 0;
    if(m_bDisabled && iCount >= 4) iButtonIndex = 3;
    elseif(m_bPressed && iCount >= 3)iButtonIndex = 2;
    elseif(m_bHovering && iCount >= 2)iButtonIndex = 1;
    elseiButtonIndex = 0;
 
    // 在指定位置绘制按钮
    intiWidth = m_pImage->GetWidth()/iCount;
    intiHeight = m_pImage->GetHeight();
    RectF grect;
    grect.X=(Gdiplus::REAL)m_rcRect.left;
    grect.Y=(Gdiplus::REAL)m_rcRect.top;
    grect.Width = (Gdiplus::REAL)m_rcRect.Width();
    grect.Height = (Gdiplus::REAL)m_rcRect.Height();
 
    graphics.DrawImage(m_pImage, grect, (Gdiplus::REAL)iWidth*iButtonIndex,0,(Gdiplus::REAL)iWidth,(Gdiplus::REAL)iHeight, UnitPixel);
 
    StringFormat stringFormat;
 
    if(m_pIcon)
    {
        PointF ptIcon(m_ptIcon.x,m_ptIcon.y);
        graphics.DrawImage(m_pIcon,ptIcon);
 
        grect.X=(Gdiplus::REAL)m_ptIcon.x + m_pIcon->GetWidth() + 2;
        grect.Width = (Gdiplus::REAL)m_rcRect.Width() - m_pIcon->GetWidth() - 2;
 
        stringFormat.SetFormatFlags( StringFormatFlagsDirectionVertical);
        stringFormat.SetAlignment(StringAlignmentCenter);
        stringFormat.SetLineAlignment(StringAlignmentNear);
    }
    else
    {
        //stringFormat.SetFormatFlags( StringFormatFlagsDirectionVertical);
        stringFormat.SetAlignment(StringAlignmentCenter);
        stringFormat.SetLineAlignment(StringAlignmentCenter);
    }
 
    if(!m_strCaption.IsEmpty())
    {
        //绘制文字
        FontFamily fontFamily(L"宋体");
        Gdiplus::Font font(&fontFamily, 10, FontStyleRegular, UnitPoint);
 
 
        CStringW strTitle(m_strCaption);
        SolidBrush brush((ARGB)Color::White);
        if(m_bDisabled)
        {
            brush.SetColor((ARGB)Color::Gray);
        }
 
        graphics.DrawString(strTitle, strTitle.GetLength(), &font,grect,&stringFormat, &brush);
    }
 
}
 
// 创建按钮
voidCDUIButton::CreateButton(LPCTSTRlpszCaption,LPRECT lpRect,CWnd* pParent, Image* pImage,UINTnCount/* = 4*/,UINTnID/* = 0*/)
{
    if(lpszCaption)
    {
        m_strCaption = lpszCaption;
    }
    m_pParent = pParent;
    m_rcRect = lpRect;
    m_pImage = pImage;
    m_nImageCount = nCount;
    m_nID = nID;
}
 
//设置按钮图标信息
void CDUIButton::SetIconInfo(Image *pIcon,CPoint ptPos/* = CPoint(5,3)*/,BOOLbRedraw/*=FALSE*/)
{
    m_pIcon = pIcon;
    m_ptIcon = CPoint(m_rcRect.left+ptPos.x,m_rcRect.top+ptPos.y);
    if(bRedraw)
    {
        m_pParent->InvalidateRect(&m_rcRect);
    }
}
 
voidCDUIButton::SetRect(LPCRECT lpRect)
{
    CPoint ptIconOrg(m_ptIcon.x - m_rcRect.left,m_ptIcon.y - m_rcRect.top);
    m_rcRect = lpRect;
    m_ptIcon = CPoint(m_rcRect.left+ptIconOrg.x,m_rcRect.top+ptIconOrg.y);
}

[5].[代码] CSkinManager h 跳至 [1] [2] [3] [4] [5] [6]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#pragma once
 
#include <map>
#include <GdiPlus.h>
usingnamespaceGdiplus;
 
 
classCSkinManager
{
private:
    CSkinManager();
    ~CSkinManager();
public:
    staticCSkinManager* GetInstance();
    void SetSkinPath(LPCTSTRlpszSkinPath);
    CString GetSkinPath();
    Image* GetSkinItem(LPCTSTRlpszFileName);
    staticvoidUnLoadSkin();
private:
    std::map<CString,Image*>  m_mapSkinItems;
    CString m_strSkinPath;
    staticCSkinManager* m_Instance;
     
    ULONG_PTRgdiplusToken;
 
};

[6].[代码] CSkinManager cpp 跳至 [1] [2] [3] [4] [5] [6]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "StdAfx.h"
#include "SkinManager.h"
 
CSkinManager* CSkinManager::m_Instance = NULL;
 
CSkinManager::CSkinManager()
{
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
 
CSkinManager::~CSkinManager()
{
    map<CString,Image*>::iterator iter;
    for(iter = m_mapSkinItems.begin();iter != m_mapSkinItems.end();iter++)
    {
        deleteiter->second;
    }
 
    GdiplusShutdown(gdiplusToken);
 
}
 
CSkinManager* CSkinManager::GetInstance()
{
    if(m_Instance==NULL)
    {
        m_Instance =newCSkinManager;
    }
 
    returnm_Instance;
}
 
void CSkinManager::SetSkinPath(LPCTSTRlpszSkinPath)
{
    m_strSkinPath = lpszSkinPath;
}
 
CString CSkinManager::GetSkinPath()
{
    returnm_strSkinPath;
}
 
Image* CSkinManager::GetSkinItem(LPCTSTRlpszFileName)
{
    Image* pImage = NULL;
    map<CString,Image*>::iterator iter;
    iter = m_mapSkinItems.find(lpszFileName);
    if(iter == m_mapSkinItems.end())
    {
        CString strImgPath = m_strSkinPath+lpszFileName;
        m_mapSkinItems[lpszFileName] = (Image*)Bitmap::FromFile(strImgPath);
        pImage = m_mapSkinItems[lpszFileName];
    }
    else
    {
        pImage = iter->second;
    }
 
    returnpImage;
}
 
void CSkinManager::UnLoadSkin()
{
    if(m_Instance)
    {
        deletem_Instance;
        m_Instance = NULL;
    }
}

本文转载自:

共有 人打赏支持
江河海流
粉丝 9
博文 44
码字总数 73431
作品 0
黄浦
C语言/C++编程学习:获取电脑开机时间

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 05/21 ⋅ 0

C语言/C++编程学习—绘制神奇代码之星空动态

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 03/26 ⋅ 0

C语言/C++程序员编程基础学习代码训练

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 03/27 ⋅ 0

VS2010/MFC编程入门教程之目录和总结(鸡啄米)

鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够。以此教程的知识为基础,学习VS2010/MFC较为深入的内容已非难事...

weixin_40647819 ⋅ 05/23 ⋅ 0

C语言/C++程序员编程学习自信心曲线图

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 05/10 ⋅ 0

什么是 C 和 C ++ 标准库?

简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的。 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? ...

oschina ⋅ 04/10 ⋅ 0

C语言/C++永远都不会过时的编程语言

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 03/30 ⋅ 0

C语言/C++编程学习强势之处的体现

C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到...

小辰带你看世界 ⋅ 05/12 ⋅ 0

《C++ primer》读后感:时代的经典

说起Lippman的C++ Primer,我总是有种特殊感情。这本书既是我进入C++领域的敲门砖,也是我第一次在网络上发表技术文章的对象。当年读书笔记中的青涩迷惘和年少轻狂都还历历在目,转眼已经从第...

凌杰_owlman ⋅ 05/15 ⋅ 0

Java程序员如何高效而优雅地入门C++

Java程序员如何高效而优雅地入门Cpp,由于工作需要,需要用C++写一些模块。关于C++ 的知识结构,虽说我有过快速学习很多新语言的经验,但对于C++ 我也算是老手,但也还需要心生敬畏,本文会从...

小欣妹妹 ⋅ 04/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 53分钟前 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部