Click here to Skip to main content
15,886,799 members
Articles / Programming Languages / C++
Article

Draw Skin Window Using Pure Win32 API

Rate me:
Please Sign up or sign in to vote.
4.35/5 (33 votes)
14 Sep 2007CPOL3 min read 139.1K   9.5K   115   23
An article to show how to draw a skin window
Screenshot - drawwindow1.gif

Introduction

How can you make an application's own skin window without MFC extension UI libraries like BGCControlBar, Xtreme Toolkit and so on? This article uses pure Win32 API to find the answer.

Contents

Windows Messages

For the beginner, I want to explain the window messages that should be processed. Anybody who wants to draw a window should process the window messages as below:

MessageDescription
WM_NCPAINTThe message is sent to a window when its frame must be painted. We should paint the window here.
WM_NCCALCSIZEThe message is sent when the size and position of a window's client area must be calculated. By processing this message, an application can control the content of the window's client area when the size or position of the window changes.
WM_NCACTIVATEThe message is sent to a window when its non-client area needs to be changed to indicate an active or inactive state.
WM_NCHITTESTThe message is sent to a window when the cursor moves or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse.
WM_NCLBUTTONUP<br />WM_NCLBUTTONDOWN<br />WM_NCLBUTTONDBLCLK<br />WM_NCRBUTTONUP<br />WM_NCRBUTTONDOWN<br />WM_NCMOUSEMOVE The message is posted when the user releases the left mouse button while the cursor is within the non-client area of the window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.
WM_GETMINMAXINFOThe message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.
WM_ACTIVATEThe message is sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously. First it is sent to the window procedure of the top-level window being deactivated and then it is sent to the window procedure of the top-level window being activated. If the windows use different input queues, the message is sent asynchronously, so the window is activated immediately.

Class SkinWindow

We should create a class named SkinWindow that takes responsibility for painting the window. The class SkinWindow defines some functions to process the special window's message.

FunctionDescription
OnNcPaintProcess message WM_NCPAINT
OnNcActiveProcess message WM_NCACTIVATE
OnNcCalcSizeProcess message WM_NCCALCSIZE
OnNcHitTestProcess message WM_NCHITTEST
OnNcLButtonUpProcess message WM_NCLBUTTONUP
OnNcLButtonDownProcess message WM_NCLBUTTONDOWN
OnNcLButtonDblClkProcess message WM_NCLBUTTONDBLCLK
OnNcMouseMoveProcess message WM_NCMOUSEMOVE
OnNcRButtonUpProcess message WM_NCRBUTTONUP
OnNcRButtonDownProcess message WM_NCRBUTTONDOWN
OnSizeProcess message WM_SIZE
OnSizingProcess message WM_SIZING
OnActiveProcess message WM_ACTIVE
OnWindowPosChangingProcess message WM_WINDOWPOSCHANGING
OnGetMinMaxInfoProcess message WM_GETMINMAXINFO
OnSetTextProcess message WM_SETTEXT
OnSysCommandProcess message WM_SYSCOMMAND

Example

Firstly, we create a new Win32 application that includes SkinWindow in its project.

C++
#include "skinwindow.h"

Secondly, we should define a global variant in the main CPP file.

C++
CSkinWindow SkinWin;

Thirdly, we load the skin from resource at the function InitInstance.

C++
SkinWin.Load(hInstance, hWnd);

Last, we should add some code in the function WndProc to process the special window's messages.

C++
// handle some special window's message here
if( SkinWin.IsHandledMessage( message ) )
    return SkinWin.WndProc( hWnd, message, wParam, lParam );

Problems/Bugs

When you size or drag and move a window as fast as you can, the monitor will flash and the window will take up more CPU percent. I've tried many approaches, but the problem persists. Is there anyone who can resolve it? The problem's picture is like below.

Screenshot - drawwindow2.gif

Additional Notes

This is by no means a finished product! This is my first attempt at writing a terribly complicated Win32 application library. I want to tell a beginner how to skin a window using pure Win32 API without MFC and give the beginner some hints to comprehensive window messages. I wanted something similar to SkinWindow in functionality, but without the overhead of MFC. There will be bugs and errors! I hope that you find this code useful. If you have any improvements/suggestions, comments/flames or questions please post them here.

History

  • 14 September, 2007 -- Original version posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer none
China China
To be, or not to be, this is question. That's are all depend on your decision. What do you think?

Comments and Discussions

 
QuestionThanks! The one working and simple example Pin
KevinSW19-Mar-14 16:58
KevinSW19-Mar-14 16:58 
Here it is 2014 as I write this but I remember downloading this years ago and finally getting around to using it.
Out of the all the web searching back then and still now it's one of the, if not the, best working examples around.
Like the title says "Win32 API", any other examples I could find were using MFC, or some other bloated GUI framework.
It's still a gem and really helped me as a launching point to get my own custom window frames going.

Now yes it has a few problems. It kind of looks like this was a working prototype, and, or some rough cut and paste from some larger project. Might have a memory leak and bug or two, parts of it are not being used, etc.
But then it just works, simple, elegant..shows you a Windows XP looking window frame on what ever Windows OS you run it on, regardless of your theme or performance settings.

On a side note I came here to give thanks and appreciation..and sure enough the "entitled" ones amongst us world of programmers has to make flaming derogatory post(s). You know like that annoying "know it all" type that you probably forced to work with (that you would rather punch in the face if you had more of a choice). The guy that thinks he knows it all, just looks at things from the surface, thinks he makes him self look smart by pointing out problems in other peoples code (just hope you don't have to look at his).
And come on, really?, this is the first time you got an access violation building someone else's code?
It should go with out saying, are you using the same compiler and dev setup, the same exact libs, and did you think of using a debug build?
You've taken the phrase: "Don't look a gift horse in the mouth" down another level. Let's see your "teeth", I mean code, first.

It was easy enough to walk though to refactor and work it into my own style and preferences.
I took the included resource frame graphics and turned the saturation all the way down and played with the brightness to get a neat dark gray look I wanted for starters.
Now I'm in the process of adding my own little button class/object to easily add more buttons to the title bar (like the way Photoshop does their detailed custom title bar et al), and now I'm taking out most of the bitmaps instead using direct rectangle and line fill blits to give my frame a more Windows 8 style square look, etc.

Again thanks for out of all the bloated, overly complicated, expensive pay skin toolkits, etc., making a good working example that anyone can build off of.

modified 19-Mar-14 23:05pm.

AnswerRe: Thanks! The one working and simple example Pin
jackyxinli20-Mar-14 20:40
jackyxinli20-Mar-14 20:40 
AnswerRe: Thanks! The one working and simple example Pin
jackyxinli20-Mar-14 20:45
jackyxinli20-Mar-14 20:45 
GeneralRe: Thanks! The one working and simple example Pin
KevinSW13-Jul-14 18:14
KevinSW13-Jul-14 18:14 
QuestionWow, Was a nice try. Pin
xox_c0bra_xox6-Dec-11 5:16
xox_c0bra_xox6-Dec-11 5:16 
AnswerRe: Wow, Was a nice try. Pin
KevinSW19-Mar-14 15:55
KevinSW19-Mar-14 15:55 
QuestionProblem with title bar Pin
Member 445058125-May-08 9:33
Member 445058125-May-08 9:33 
AnswerRe: Problem with title bar [modified] Pin
jackyxinli26-May-08 14:38
jackyxinli26-May-08 14:38 
Questioni want to ask,what developtool r u do u use? Pin
macroideal29-Apr-08 15:28
macroideal29-Apr-08 15:28 
AnswerRe: i want to ask,what developtool r u do u use? Pin
jackyxinli29-Apr-08 21:15
jackyxinli29-Apr-08 21:15 
GeneralScrollBar Pin
salah_nrg9-Apr-08 18:14
salah_nrg9-Apr-08 18:14 
GeneralVery good, but..... Pin
markin.alves29-Nov-07 6:30
markin.alves29-Nov-07 6:30 
GeneralRe: Very good, but..... Pin
jackyxinli1-Dec-07 14:46
jackyxinli1-Dec-07 14:46 
Generalgood work Pin
braindamage1029-Oct-07 7:47
braindamage1029-Oct-07 7:47 
GeneralI noticed the lag when resizing, Pin
code_discuss18-Oct-07 22:30
code_discuss18-Oct-07 22:30 
GeneralRe: I noticed the lag when resizing, Pin
gdier29-Oct-07 4:19
gdier29-Oct-07 4:19 
GeneralImpressive even Pin
John R. Shaw20-Sep-07 19:23
John R. Shaw20-Sep-07 19:23 
GeneralRe: Impressive even Pin
jackyxinli22-Sep-07 18:40
jackyxinli22-Sep-07 18:40 
QuestionWhat about WS_SYSMENU style? Pin
Dandy Cheung17-Sep-07 3:54
Dandy Cheung17-Sep-07 3:54 
AnswerRe: What about WS_SYSMENU style? Pin
Dandy Cheung17-Sep-07 4:02
Dandy Cheung17-Sep-07 4:02 
QuestionCould you check the menu painting ? Pin
Kochise14-Sep-07 21:13
Kochise14-Sep-07 21:13 
GeneralInteresting PinPopular
David Nash14-Sep-07 18:17
David Nash14-Sep-07 18:17 
GeneralRe: Interesting Pin
yctsai1-Nov-07 21:31
yctsai1-Nov-07 21:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.