1079 lines
40 KiB
C++
1079 lines
40 KiB
C++
// ==========================================================================
|
|
// Class Specification :
|
|
// COXCaptionInfo & COXCaptionPainter
|
|
// ==========================================================================
|
|
|
|
// Version: 9.3
|
|
|
|
// This software along with its related components, documentation and files ("The Libraries")
|
|
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
|
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
|
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
|
// to obtain this file, or directly from our office. For a copy of the license governing
|
|
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
|
|
|
// //////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _CAPTIONPAINTER_H
|
|
#define _CAPTIONPAINTER_H
|
|
|
|
#if _MSC_VER >= 1000
|
|
#pragma once
|
|
#endif // _MSC_VER >= 1000
|
|
|
|
#include "OXDllExt.h"
|
|
|
|
#ifndef __AFXTEMPL_H__
|
|
#include <afxtempl.h>
|
|
#define __AFXTEMPL_H__
|
|
#endif
|
|
|
|
#ifndef __AFXPRIV_H__
|
|
#include <afxpriv.h>
|
|
#define __AFXPRIV_H__
|
|
#endif
|
|
|
|
#include "OXHookWnd.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// IMPORTANT !!!
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// if you wouldn't need to save state of caption into registry then
|
|
// you probably wouldn't want to include source code for
|
|
// COXRegistryValFile class into your project (that is a must if you
|
|
// call COXCaptionPainter::SaveState() and/or COXCaptionPainter::LoadState()).
|
|
// If this is a case then you have to define include in you stdafx.h file
|
|
// next code:
|
|
//
|
|
// #define OXCP_NO_SAVESTATE
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// types of gradient alignment: left, right and center
|
|
#define ID_GRADIENT_LEFT 0x00000000
|
|
#define ID_GRADIENT_CENTER 0x00000001
|
|
#define ID_GRADIENT_RIGHT 0x00000002
|
|
|
|
// types of algorithm used to draw gradient caption
|
|
#define ID_GRADIENT_LINEAR 0x00000000
|
|
#define ID_GRADIENT_SQUARE 0x00000001
|
|
|
|
// generic constant used to define that none of custom color was set
|
|
#define ID_OXCP_COLOR_NONE 0xffffffff
|
|
|
|
// inner constatnts used in SetHackStyle and SetHackStyleEx functions
|
|
#define ID_OXHACK_ADDSTYLE 0x00000000
|
|
#define ID_OXHACK_REMOVESTYLE 0x00000001
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Class COXCaptionInfo defines caption attributes. This class is heavily
|
|
// used by COXCaptionPainter class. The main feature of this class is
|
|
// that it is serializable. That means that you can save caption info
|
|
// in a file or registry.
|
|
//
|
|
class OX_CLASS_DECL COXCaptionInfo : public CObject
|
|
{
|
|
|
|
DECLARE_SERIAL(COXCaptionInfo)
|
|
|
|
// member variables
|
|
protected:
|
|
// Background color, by default it is set to ID_OXCP_COLOR_NONE that means
|
|
// that COXCaptionPainter will use standard color to fill caption
|
|
COLORREF m_clrBackground;
|
|
|
|
// If TRUE then COXCaptionPainter will draw caption gradiently
|
|
BOOL m_bGradient;
|
|
|
|
// Gradient filling means that caption will be drawn using set of colors
|
|
// from m_clrBackground to black. Gradient alignment is defined by location
|
|
// of black color in the caption. At the moment next are defined:
|
|
// ID_GRADIENT_LEFT
|
|
// ID_GRADIENT_CENTER
|
|
// ID_GRADIENT_RIGHT
|
|
UINT m_nGradientAlignment;
|
|
|
|
// Gradient Filling could be accomplished using different algorithm. We support
|
|
// two algorithms: linear and squared, that are defined by next constants:
|
|
// ID_GRADIENT_LINEAR
|
|
// ID_GRADIENT_SQUARE
|
|
//
|
|
// Linear algorithm fill caption from black to m_clrBackground using next formula:
|
|
//
|
|
// color = m_clrBackground * r
|
|
//
|
|
// where r is the ratio x/w, which ranges from 0 (x=0, left) to 1 (x=w, right).
|
|
// This results in a mostly black title bar, since we humans don't distinguish
|
|
// dark colors as well as light ones.
|
|
// Squared algorithm resolves this problem. It used next formula:
|
|
//
|
|
// color = m_clrBackground * [1-(1-r)^2]
|
|
//
|
|
// which still equals black when r=0 and CaptionColor when r=1, but spends more
|
|
// time near m_clrBackground. For example, when r=0.5, the multiplier is
|
|
// [1-(1-.5)^2] = 0.75, closer to 1 than 0.5. Above formula is equivalent to
|
|
//
|
|
// color = CaptionColor - (CaptionColor*(w-x)*(w-x))/(w*w)
|
|
//
|
|
// The computation looks horrendous, but it's only done once each
|
|
// time the caption changes size; thereafter BitBlt'ed to the screen.
|
|
UINT m_nGradientAlgorithm;
|
|
|
|
// The number of color shades used for gradient filling. By default we use 64 shades
|
|
UINT m_nNumberShade;
|
|
|
|
// The font used to draw window's text. By default we use standard font used to
|
|
// draw in a caption.
|
|
CFont m_font;
|
|
|
|
// The font used to draw window's text (Small caption). By default we use
|
|
// standard font used to draw in a caption.
|
|
CFont m_fontSm;
|
|
|
|
// Color used to draw window's text. By default it is set to ID_OXCP_COLOR_NONE
|
|
// that means that COXCaptionPainter will use standard color to draw window's text
|
|
COLORREF m_clrText;
|
|
|
|
// special format to draw window's text. Could be a combination of:
|
|
// DT_BOTTOM - Justifies the text to the bottom of the caption rectangle.
|
|
// This value must be combined with DT_SINGLELINE.
|
|
// DT_CENTER - Centers text horizontally in the caption rectangle.
|
|
// DT_EDITCONTROL - Duplicates the text-displaying characteristics of
|
|
// a multiline edit control. Specifically, the average
|
|
// character width is calculated in the same manner as for
|
|
// an edit control, and the function does not display
|
|
// a partially visible last line.
|
|
// DT_END_ELLIPSIS
|
|
// or DT_PATH_ELLIPSIS- Replaces part of the given string with ellipses,
|
|
// if necessary, so that the result fits in the caption
|
|
// rectangle. The given string is not modified unless
|
|
// the DT_MODIFYSTRING flag is specified. You can specify
|
|
// DT_END_ELLIPSIS to replace characters at the end of the
|
|
// string, or DT_PATH_ELLIPSIS to replace characters in the
|
|
// middle of the string. If the string contains backslash (\)
|
|
// characters, DT_PATH_ELLIPSIS preserves as much as
|
|
// possible of the text after the last backslash.
|
|
// DT_EXPANDTABS - Expands tab characters. The default number of characters
|
|
// per tab is eight.
|
|
// DT_EXTERNALLEADING - Includes the font external leading in line height.
|
|
// Normally, external leading is not included in the height
|
|
// of a line of text.
|
|
// DT_LEFT - Aligns text to the left.
|
|
// DT_MODIFYSTRING - Modifies the given string to match the displayed text.
|
|
// This flag has no effect unless the DT_END_ELLIPSIS or
|
|
// DT_PATH_ELLIPSIS flag is specified.
|
|
// DT_NOPREFIX - Turns off processing of prefix characters. Normally,
|
|
// the mnemonic-prefix character & is interpreted
|
|
// as a directive to underscore the character that follows,
|
|
// and the mnemonic-prefix characters && as a directive to
|
|
// print a single &. By specifying DT_NOPREFIX,
|
|
// this processing is turned off.
|
|
// DT_RIGHT - Aligns text to the right.
|
|
// DT_RTLREADING - Layout in right to left reading order for bi-directional
|
|
// text when the font selected into the hdc is a Hebrew or
|
|
// Arabic font. The default reading order for all text is
|
|
// left to right.
|
|
// DT_SINGLELINE - Displays text on a single line only. Carriage returns
|
|
// and linefeeds do not break the line.
|
|
// DT_TOP - Top-justifies text (single line only).
|
|
// DT_VCENTER - Centers text vertically (single line only).
|
|
// DT_WORDBREAK - Breaks words. Lines are automatically broken between
|
|
// words if a word would extend past the edge of the
|
|
// caption rectangle. A carriage return-linefeed sequence
|
|
// also breaks the line.
|
|
// DT_WORD_ELLIPSIS- Truncates text that does not fit in the caption rectangle
|
|
// and adds ellipses.
|
|
//
|
|
// By default we use DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS
|
|
UINT m_nTextFormat;
|
|
|
|
|
|
public:
|
|
virtual void Serialize(CArchive& ar);
|
|
|
|
private:
|
|
// helper function for font serialization
|
|
void SerializeFont(CArchive& ar, CFont* pFont);
|
|
|
|
public:
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Constructs the object
|
|
COXCaptionInfo();
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Destroys the object
|
|
virtual ~COXCaptionInfo() {}
|
|
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets all caption info properties to its default value
|
|
void Reset();
|
|
|
|
|
|
// --- In : clrBackground - background color. If specified as
|
|
// ID_OXCP_COLOR_NONE then standard color
|
|
// will be used
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets caption's background color
|
|
inline void SetBackgroundColor(COLORREF clrBackground=ID_OXCP_COLOR_NONE) {
|
|
m_clrBackground=clrBackground;
|
|
}
|
|
|
|
// --- In : bActive - TRUE if background color is requsted for caption in
|
|
// the active state, or FALSE if in the inactive.
|
|
// --- Out :
|
|
// --- Returns: Caption's background color. If it was set as ID_OXCP_COLOR_NONE
|
|
// then standard color will be returned (that's why we need bActive).
|
|
// --- Effect :
|
|
COLORREF GetBackgroundColor(BOOL bActive) const;
|
|
|
|
|
|
// --- In : clrText - color to draw window's text. If specified as
|
|
// ID_OXCP_COLOR_NONE then standard color will be used
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets color to draw window's text.
|
|
inline void SetTextColor(COLORREF clrText=ID_OXCP_COLOR_NONE) { m_clrText=clrText; }
|
|
|
|
// --- In : bActive - TRUE if text color is requsted for caption in
|
|
// the active state, or FALSE if in the inactive.
|
|
// --- Out :
|
|
// --- Returns: Color to draw window's text. If it was set as ID_OXCP_COLOR_NONE
|
|
// then standard color will be returned (that's why we need bActive).
|
|
// --- Effect :
|
|
COLORREF GetTextColor(BOOL bActive) const;
|
|
|
|
|
|
// --- In : bGradient - if TRUE caption will be filled gradiently,
|
|
// otherwise plain.
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets type of caption filling.
|
|
inline void SetGradient(BOOL bGradient) { m_bGradient=bGradient; }
|
|
|
|
// --- In : bGradient - if TRUE caption will be filled gradiently,
|
|
// otherwise plain.
|
|
// --- Out :
|
|
// --- Returns: TRUE if caption is filled gradiently, or FALSE otherwise.
|
|
// --- Effect :
|
|
inline BOOL GetGradient() const { return m_bGradient; }
|
|
|
|
|
|
// --- In : nGradientAlignment - type of gradient alignment.
|
|
// Next are allowed:
|
|
//
|
|
// ID_GRADIENT_LEFT
|
|
// ID_GRADIENT_CENTER
|
|
// ID_GRADIENT_RIGHT
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets gradient alignment.
|
|
inline void SetGradientAlignment(UINT nGradientAlignment) {
|
|
ASSERT(nGradientAlignment==ID_GRADIENT_LEFT ||
|
|
nGradientAlignment==ID_GRADIENT_CENTER ||
|
|
nGradientAlignment==ID_GRADIENT_RIGHT);
|
|
m_nGradientAlignment=nGradientAlignment;
|
|
}
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns: Gradient alignment.
|
|
// --- Effect :
|
|
inline UINT GetGradientAlignment() const { return m_nGradientAlignment; }
|
|
|
|
|
|
// --- In : nGradientAlgorithm - type of gradient algorithm.
|
|
// Next are allowed:
|
|
//
|
|
// ID_GRADIENT_LINEAR
|
|
// ID_GRADIENT_SQUARE
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets gradient algorithm.
|
|
//
|
|
// Gradient Filling could be accomplished using different algorithm. We support
|
|
// two algorithms: linear and squared, that are defined by next constants:
|
|
// ID_GRADIENT_LINEAR
|
|
// ID_GRADIENT_SQUARE
|
|
//
|
|
// Linear algorithm fill caption from black to m_clrBackground using next formula:
|
|
//
|
|
// color = m_clrBackground * r
|
|
//
|
|
// where r is the ratio x/w, which ranges from 0 (x=0, left) to 1 (x=w, right).
|
|
// This results in a mostly black title bar, since we humans don't distinguish
|
|
// dark colors as well as light ones.
|
|
// Squared algorithm resolves this problem. It used next formula:
|
|
//
|
|
// color = m_clrBackground * [1-(1-r)^2]
|
|
//
|
|
// which still equals black when r=0 and CaptionColor when r=1, but spends more
|
|
// time near m_clrBackground. For example, when r=0.5, the multiplier is
|
|
// [1-(1-.5)^2] = 0.75, closer to 1 than 0.5. Above formula is equivalent to
|
|
//
|
|
// color = CaptionColor - (CaptionColor*(w-x)*(w-x))/(w*w)
|
|
//
|
|
// The computation looks horrendous, but it's only done once each
|
|
// time the caption changes size; thereafter BitBlt'ed to the screen.
|
|
//
|
|
inline void SetGradientAlgorithm(UINT nGradientAlgorithm) {
|
|
ASSERT(nGradientAlgorithm==ID_GRADIENT_LINEAR ||
|
|
nGradientAlgorithm==ID_GRADIENT_SQUARE);
|
|
m_nGradientAlgorithm=nGradientAlgorithm;
|
|
}
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns: Gradient algorithm.
|
|
// --- Effect :
|
|
inline UINT GetGradientAlgorithm() const { return m_nGradientAlgorithm; }
|
|
|
|
|
|
// --- In : plf - point to LOGFONT structure.
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise
|
|
// --- Effect : Sets font used to draw text in caption. By default we use
|
|
// current window font. You can set whatever font you want to
|
|
// display the caption text, but remember that it is up to you
|
|
// to adjust the height of the caption. If plf is NULL then
|
|
// standard font will be used to draw text in caption.
|
|
BOOL SetCaptionLogFont(LOGFONT* plf=NULL);
|
|
|
|
// --- In : plf - point to LOGFONT structure.
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise
|
|
// --- Effect : Sets font used to draw text in caption (Small caption).
|
|
// By default we use current window font. You can set
|
|
// whatever font you want to display the caption text,
|
|
// but remember that it is up to you to adjust the height
|
|
// of the caption. If plf is NULL then standard font will
|
|
// be used to draw text in caption.
|
|
BOOL SetSmCaptionLogFont(LOGFONT* plf=NULL);
|
|
|
|
|
|
// --- In : plf - point to LOGFONT structure.
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise
|
|
// --- Effect : Fills plf with font used to draw text in caption.
|
|
BOOL GetCaptionLogFont(LOGFONT* plf) const;
|
|
|
|
// --- In : plf - point to LOGFONT structure.
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise
|
|
// --- Effect : Fills plf with font used to draw text in caption
|
|
// (Small Caption).
|
|
BOOL GetSmCaptionLogFont(LOGFONT* plf) const;
|
|
|
|
|
|
// --- In : nTextFormat - format used to draw text in caption
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets format to display window's text.
|
|
// Could be a combination of:
|
|
// DT_BOTTOM - Justifies the text to the bottom of the caption rectangle.
|
|
// This value must be combined with DT_SINGLELINE.
|
|
// DT_CENTER - Centers text horizontally in the caption rectangle.
|
|
// DT_EDITCONTROL - Duplicates the text-displaying characteristics of
|
|
// a multiline edit control. Specifically, the average
|
|
// character width is calculated in the same manner as for
|
|
// an edit control, and the function does not display
|
|
// a partially visible last line.
|
|
// DT_END_ELLIPSIS
|
|
// or DT_PATH_ELLIPSIS- Replaces part of the given string with ellipses,
|
|
// if necessary, so that the result fits in the caption
|
|
// rectangle. The given string is not modified unless
|
|
// the DT_MODIFYSTRING flag is specified. You can specify
|
|
// DT_END_ELLIPSIS to replace characters at the end of the
|
|
// string, or DT_PATH_ELLIPSIS to replace characters in the
|
|
// middle of the string. If the string contains backslash (\)
|
|
// characters, DT_PATH_ELLIPSIS preserves as much as
|
|
// possible of the text after the last backslash.
|
|
// DT_EXPANDTABS - Expands tab characters. The default number of characters
|
|
// per tab is eight.
|
|
// DT_EXTERNALLEADING - Includes the font external leading in line height.
|
|
// Normally, external leading is not included in the height
|
|
// of a line of text.
|
|
// DT_LEFT - Aligns text to the left.
|
|
// DT_MODIFYSTRING - Modifies the given string to match the displayed text.
|
|
// This flag has no effect unless the DT_END_ELLIPSIS or
|
|
// DT_PATH_ELLIPSIS flag is specified.
|
|
// DT_NOPREFIX - Turns off processing of prefix characters. Normally,
|
|
// the mnemonic-prefix character & is interpreted
|
|
// as a directive to underscore the character that follows,
|
|
// and the mnemonic-prefix characters && as a directive to
|
|
// print a single &. By specifying DT_NOPREFIX,
|
|
// this processing is turned off.
|
|
// DT_RIGHT - Aligns text to the right.
|
|
// DT_RTLREADING - Layout in right to left reading order for bi-directional
|
|
// text when the font selected into the hdc is a Hebrew or
|
|
// Arabic font. The default reading order for all text is
|
|
// left to right.
|
|
// DT_SINGLELINE - Displays text on a single line only. Carriage returns
|
|
// and linefeeds do not break the line.
|
|
// DT_TOP - Top-justifies text (single line only).
|
|
// DT_VCENTER - Centers text vertically (single line only).
|
|
// DT_WORDBREAK - Breaks words. Lines are automatically broken between
|
|
// words if a word would extend past the edge of the
|
|
// caption rectangle. A carriage return-linefeed sequence
|
|
// also breaks the line.
|
|
// DT_WORD_ELLIPSIS- Truncates text that does not fit in the caption rectangle
|
|
// and adds ellipses.
|
|
inline void SetTextFormat(UINT nTextFormat) { m_nTextFormat=nTextFormat; }
|
|
|
|
// --- In : nTextFormat - format used to draw text in caption
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets format to display window's text.
|
|
inline UINT GetTextFormat() const { return m_nTextFormat; }
|
|
|
|
|
|
// --- In : nNumberShade - the number of color shades
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets the number of color shades used in gradient filling.
|
|
inline void SetNumberShade(UINT nNumberShade) {
|
|
ASSERT(nNumberShade>0);
|
|
if(nNumberShade>0)
|
|
m_nNumberShade=nNumberShade;
|
|
}
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns: The number of color shades used in gradient filling.
|
|
// --- Effect :
|
|
inline UINT GetNumberShade() const { return m_nNumberShade; }
|
|
|
|
// assignment operator
|
|
COXCaptionInfo& operator=(const COXCaptionInfo& ci);
|
|
};
|
|
|
|
////////////////////////
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Generic caption painter. Derived from COXHookWnd - generic class that is
|
|
// used to subclass any CWnd and provides capability to handle any message
|
|
// routed to the hooked window before it. Handles WM_NCPAINT, WM_NCACTIVATE,
|
|
// and whole bunch of other messages to handle drawing custom captions.
|
|
// To use it:
|
|
//
|
|
// 1) call Attach from your window's OnCreate function.
|
|
//
|
|
// 2) to set caption properties create COXCaptionInfo object or get
|
|
// associated one using GetCaptionInfo() function. COXCaptionPainter
|
|
// uses different COXCaptionInfo object for active and inactive state.
|
|
//
|
|
// 3) change any COXCaptionInfo properties you want to.
|
|
//
|
|
// 4) set updated COXCaptionInfo object to COXCaptionPainter object using
|
|
// SetCaptionInfo() function.
|
|
//
|
|
// 5) invalidate window's caption using SendMessage(WM_NCPAINT) in order to
|
|
// redraw it
|
|
//
|
|
//
|
|
// Additional functionality:
|
|
//
|
|
// 1) you can load and/or save caption info in the registry using functions
|
|
// SaveState and LoadState
|
|
//
|
|
// 2) you can get any COXCaptionPainter object associated with any window
|
|
// calling GetCaptionPainter() function and copy all properties from
|
|
// any COXCaptionPainter object to the COXCaptionPainter associated with
|
|
// any window using SetCaptionPainter(). These function are especially
|
|
// useful when you want to set the same COXCaptionPainter properties
|
|
// for a set of windows (e.g. if all properties of parent window should be
|
|
// copied to all siblings)
|
|
//
|
|
class OX_CLASS_DECL COXCaptionPainter : public COXHookWnd
|
|
{
|
|
protected:
|
|
DECLARE_DYNAMIC(COXCaptionPainter);
|
|
|
|
// Size of caption rectangle. We always keep this information as flag
|
|
// that indicate that we have to rebuild bitmaps for caption.
|
|
CSize m_sizeCaption;
|
|
|
|
// Bitmap for active captions
|
|
CBitmap m_bmActive;
|
|
// Bitmap for inactive captions
|
|
CBitmap m_bmInactive;
|
|
// Active/inactive state
|
|
BOOL m_bActive;
|
|
// The problem is that while minimizing, maximizing, tiling, cascading or
|
|
// restoring the size of window Windows by default applies special animation
|
|
// effects using standard colors. And if you set your own background colors
|
|
// it could be rather annoying to see animation with different color.
|
|
// By default we turn off animation to eliminate this problem. Of course you
|
|
// can turn off this functionality using SetAnimation() function. Next property
|
|
// is set to TRUE if animation will be displayed, or FALSE otherwise
|
|
// Window minimize/maximize animation
|
|
BOOL m_bAnimation;
|
|
|
|
// We keep two COXCaptionInfo objects for two caption state: active and inactive
|
|
COXCaptionInfo m_ciActive;
|
|
COXCaptionInfo m_ciInactive;
|
|
|
|
// Windows is really inconsistent in its way of drawing caption. To eliminate
|
|
// some of undesirable Windows drawings we use some hacks: we change style
|
|
// (or extended style) of hooked window for a period of standard Windows handling
|
|
// of some messages and then set it again. m_bHackStyleSet property is set to
|
|
// TRUE if any hack was applied to hooked window and we save original window style
|
|
// in m_dwSavedStyle. The same consideration applied to m_bHackStyleExSet and
|
|
// m_dwSavedStyleEx properties (extended style)
|
|
BOOL m_bHackStyleSet;
|
|
LONG m_dwSavedStyle;
|
|
BOOL m_bHackStyleExSet;
|
|
LONG m_dwSavedStyleEx;
|
|
BOOL m_bUpdate;
|
|
// defines a number of bits used to represent colors in current video mode
|
|
UINT m_nColorBits;
|
|
|
|
// last used window text
|
|
CString m_sWindowText;
|
|
|
|
// flags that defines the actions that should be taken when
|
|
// the hooked window is in idle state
|
|
enum IdleFlags { oxidleRedrawCaption=1 };
|
|
int m_nIdleFlags;
|
|
|
|
|
|
protected:
|
|
// The heart of the class. Handle all needed messages. While deriving
|
|
// your own class make sure to call this function. I wouldn't recommend you
|
|
// to change anything in it
|
|
//
|
|
// --- In : msg - message ID
|
|
// wp - WPARAM
|
|
// lp - LPARAM
|
|
// --- Out :
|
|
// --- Returns: result of message handling. Different for different messages.
|
|
// --- Effect : Sets the number of color shades used in gradient filling.
|
|
virtual LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp);
|
|
|
|
virtual void OnNcPaint(HRGN hUpdateRgn);
|
|
virtual BOOL OnNcActivate(BOOL bActive);
|
|
virtual void OnSetText(LPCTSTR lpText);
|
|
virtual LRESULT OnNCLButtonDown(WPARAM wp, LPARAM lp);
|
|
|
|
// Windows is really inconsistent in its way of drawing caption. To eliminate
|
|
// some of undesirable Windows drawings we use some hacks: we change style
|
|
// (or extended style) of hooked window for a period of standard Windows handling
|
|
// of some messages and then set it again. Next functions are especially designed
|
|
// to provide such functionality.
|
|
//
|
|
// --- In : dwStyle - any combination of window's styles
|
|
// nAction - if equals to ID_OXHACK_ADDSTYLE then
|
|
// dwStyle will be set to hooked window,
|
|
// if equals to ID_OXHACK_REMOVESTYLE then
|
|
// dwStyle will be removed from hooked window,
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Change style of hooked window to force Windows to handle
|
|
// some messages the way we like.
|
|
void SetHackStyle(LONG dwStyle, UINT nAction=ID_OXHACK_REMOVESTYLE);
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Set original style to hooked window.
|
|
void RemoveHackStyle();
|
|
|
|
|
|
// --- In : dwStyleEx - any combination of window's extended styles
|
|
// nAction - if equals to ID_OXHACK_ADDSTYLE then
|
|
// dwStyleEx will be set to hooked window,
|
|
// if equals to ID_OXHACK_REMOVESTYLE then
|
|
// dwStyleEx will be removed from hooked window,
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Change extended style of hooked window to force Windows to handle
|
|
// some messages the way we like.
|
|
void SetHackStyleEx(LONG dwStyleEx, UINT nAction=ID_OXHACK_REMOVESTYLE);
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Set original extended style to hooked window.
|
|
void RemoveHackStyleEx();
|
|
|
|
// --- In : msg - message ID
|
|
// wp - WPARAM
|
|
// lp - LPARAM
|
|
// --- Out :
|
|
// --- Returns: result of message handling. Different for different messages.
|
|
// --- Effect : The problem is that while minimizing, maximizing, tiling,
|
|
// cascading or restoring the size of window Windows by default
|
|
// applies special animation effects using standard colors.
|
|
// And if you set your own background colors it could be rather
|
|
// annoying to see animation with different color. By default we
|
|
// turn off animation to eliminate this problem. Of course you
|
|
// can turn off this functionality using SetAnimation() function.
|
|
// If animation wasn't turned of then this function juct handle
|
|
// the message, otherwise before handling the message animation
|
|
// flag will be turned off and after handling set to its
|
|
// previous condition.
|
|
LRESULT HackAnimation(UINT msg, WPARAM wp, LPARAM lp);
|
|
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Draws caption.
|
|
virtual void DrawCaption();
|
|
|
|
|
|
// Helper function
|
|
// --- In : rect - rectangle to copy coordinates of caption rectangle
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Calculates caption rectangle.
|
|
void GetCaptionRect(CRect& rect);
|
|
|
|
|
|
// Helper function
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns: number of bits used to represent colors in current video mode.
|
|
// --- Effect :
|
|
UINT GetNumColorBits();
|
|
|
|
inline void DelayDrawCaption() { m_nIdleFlags|=oxidleRedrawCaption; }
|
|
|
|
|
|
public:
|
|
// Registered messages to set/get COXCaptionPainter object. Used in
|
|
// SetCaptionPainter() and GetCaptionPainter() functions. You can
|
|
// use them independently sending a message to hooked window:
|
|
// WPARAM is not used, LPARAM is set to pointer to COXCaptionPainter
|
|
// object. E.g. if you want to set the same COXCaptionPainter properties
|
|
// for all child windows you can call next function:
|
|
//
|
|
// SendMessageToDescendants(COXCaptionPainter::m_nSetCaptionPainter,0,
|
|
// (LPARAM)&m_Caption);
|
|
//
|
|
static UINT m_nSetCaptionPainter;
|
|
static UINT m_nGetCaptionPainter;
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Constructs the object
|
|
COXCaptionPainter();
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Destroys the object
|
|
virtual ~COXCaptionPainter();
|
|
|
|
|
|
// --- In : pWnd - pointer to created window to be hooked
|
|
// --- Out :
|
|
// --- Returns: TRUE if pWnd was successfully hooked, otherwise FALSE
|
|
// --- Effect : Hooked window
|
|
BOOL Attach(CWnd* pWnd);
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Unhooked attached window if any was hooked
|
|
void Detach();
|
|
|
|
|
|
// --- In : bActive - TRUE if you want to get COXCaptionInfo object
|
|
// for active state or FALSE - for inactive state.
|
|
// --- Out :
|
|
// --- Returns: pointer to corresponding COXCaptionInfo object
|
|
// --- Effect :
|
|
inline COXCaptionInfo* GetCaptionInfo(BOOL bActive) {
|
|
return bActive ? &m_ciActive : &m_ciInactive;
|
|
}
|
|
|
|
// --- In : pCI - pointer to COXCaptionInfo object
|
|
// bActive - TRUE if you want to set COXCaptionInfo object
|
|
// for active state or FALSE - for inactive state.
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets caption properties
|
|
void SetCaptionInfo(COXCaptionInfo* pCI, BOOL bActive);
|
|
|
|
|
|
// --- In : pWnd - pointer to hooked window
|
|
// pCP - pointer to COXCaptionPainter object where
|
|
// information will be saved
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise.
|
|
// --- Effect : Retrieves COXCaptionPainter object associated with pWnd
|
|
static BOOL GetCaptionPainter(CWnd* pWnd, COXCaptionPainter* pCP);
|
|
|
|
// --- In : pWnd - pointer to hooked window.
|
|
// pCP - pointer to COXCaptionPainter object
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise.
|
|
// --- Effect : Copy all properties from pCP to COXCaptionPainter object
|
|
// associated with pWnd
|
|
static BOOL SetCaptionPainter(CWnd* pWnd, COXCaptionPainter* pCP);
|
|
|
|
|
|
// --- In : pDC - pointer to device context to draw in
|
|
// pCI - pointer to COXCaptionInfo object with all
|
|
// caption's properties.
|
|
// pCaptionRect- pointer to caption's rect to draw in
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Draws caption background using caption's properties.
|
|
// Declared as virtual so you can provide your own drawing routine.
|
|
virtual void DrawCaptionBackground(CDC* pDC, const COXCaptionInfo* pCI,
|
|
const CRect* pCaptionRect);
|
|
|
|
// --- In : pDC - pointer to device context to draw in
|
|
// pCI - pointer to COXCaptionInfo object with all
|
|
// caption's properties.
|
|
// pCaptionSize- pointer to caption's size
|
|
// --- Out :
|
|
// --- Returns: width of all drawn buttons with all gaps.
|
|
// --- Effect : Draws window's standard buttons (minimize, maximize, close,
|
|
// restore, help). Declared as virtual so you can provide your
|
|
// own drawing routine.
|
|
virtual int DrawCaptionButtons(CDC* pDC, const COXCaptionInfo* pCI,
|
|
const CSize* pCaptionSize);
|
|
|
|
// --- In : pDC - pointer to device context to draw in
|
|
// pCI - pointer to COXCaptionInfo object with all
|
|
// caption's properties.
|
|
// pCaptionSize- pointer to caption's size
|
|
// --- Out :
|
|
// --- Returns: width of drawn icon with all gaps.
|
|
// --- Effect : Draws window's icon. Declared as virtual so you can provide
|
|
// your own drawing routine.
|
|
virtual int DrawCaptionIcon(CDC* pDC, const COXCaptionInfo* pCI,
|
|
const CSize* pCaptionSize);
|
|
|
|
// --- In : pDC - pointer to device context to draw in
|
|
// pCI - pointer to COXCaptionInfo object with all
|
|
// caption's properties.
|
|
// pCaptionSize- pointer to caption's size
|
|
// pIndentsSize- pointer to CSize object that represents
|
|
// indents from caption left/right sides of
|
|
// caption to draw window's text in where
|
|
// cx - indent from the left side of caption
|
|
// cy - indent from the right side of caption
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Draws window's text. Declared as virtual so you can provide
|
|
// your own drawing routine.
|
|
virtual void DrawCaptionText(CDC* pDC, const COXCaptionInfo* pCI,
|
|
const CSize* pCaptionSize,
|
|
const CSize* pIndentsSize);
|
|
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Resets size of caption that will eventually cause
|
|
// rebuilding of bitmaps for active/inactive caption
|
|
inline void Reset() { m_sizeCaption.cx=0; m_sizeCaption.cy=0; }
|
|
|
|
|
|
// --- In : bAnimation - if equals FALSE then we remove animation
|
|
// effects that Windows used while minimizing,
|
|
// maximizing, tiling, cascading or restoring
|
|
// the size of a window; if equals TRUE then
|
|
// we won't try to remove it. By default, it is
|
|
// set to FALSE.
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect :
|
|
inline void SetAnimation(BOOL bAnimation) { m_bAnimation=bAnimation; }
|
|
|
|
// --- In : bAnimation - if equals TRUE then we remove animation
|
|
// effects that Windows used while minimizing,
|
|
// maximizing, tiling, cascading or restoring
|
|
// the size of a window; if equals FALSE then
|
|
// we won't try to remove it.
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect :
|
|
inline BOOL GetAnimation() { return m_bAnimation; }
|
|
|
|
#ifndef OXCP_NO_SAVESTATE
|
|
// Save to and load from registry (or *.ini file) state of caption
|
|
// These functions require using COXRegistryValFile class. If you
|
|
// are not going to use them then you can include in your stdafx.h
|
|
// file next code:
|
|
//
|
|
// #define OXCP_NO_SAVESTATE
|
|
//
|
|
// In this case you don't need to include into your project references
|
|
// to source code for COXRegistryValFile class.
|
|
//
|
|
// --- In : lpszProfileName - name .ini file or hive in registry where
|
|
// all information about COXCaptionPainter
|
|
// will be saved.
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise.
|
|
// --- Effect : Saves COXCaptionPainter state into registry or .ini file
|
|
BOOL SaveState(LPCTSTR lpszProfileName);
|
|
|
|
// --- In : lpszProfileName - name of .ini file or hive in registry where
|
|
// all information about COXCaptionPainter
|
|
// was saved.
|
|
// bApply - if equals TRUE then COXCaptionPainter will be
|
|
// to redraw caption.
|
|
//
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise.
|
|
// --- Effect : Loads COXCaptionPainter state from registry or *.ini file
|
|
BOOL LoadState(LPCTSTR lpszProfileName, BOOL bApply=TRUE);
|
|
#endif // OXCP_NO_SAVESTATE
|
|
|
|
private:
|
|
static DWORD GetDllVersion(LPCTSTR lpszDllName);
|
|
BOOL IsAppSkinned();
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
class OX_CLASS_DECL COXCaptionPainterOrganizer
|
|
{
|
|
// Construction
|
|
public:
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Constructs the object
|
|
COXCaptionPainterOrganizer() :
|
|
m_pfnOldCBTHookProc(NULL),
|
|
m_dwThreadID(NULL),
|
|
m_pfnOldGetMessageHookProc(NULL) {};
|
|
|
|
|
|
// --- In : dwThreadID - thread ID which all windows will be attached
|
|
// to caption painter objects. By default we
|
|
// use the current process thread
|
|
// --- Out :
|
|
// --- Returns: TRUE if all windows created by the specified thread were
|
|
// successfully hooked, otherwise FALSE
|
|
// --- Effect : Creates COXCaptionPainter objects for all windows created
|
|
// by the specified thread. The windows
|
|
// that will be created by the thread in the future will be
|
|
// attached as soon as they will be created. Whenever a window
|
|
// is attached it uses the caption settings of the
|
|
// mainframe window
|
|
BOOL AttachAllInThread(DWORD dwThreadID=::GetCurrentThreadId());
|
|
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns: TRUE if all windows were successfully unhooked,
|
|
// otherwise FALSE
|
|
// --- Effect : Detaches all previously attached windows that has been
|
|
// created by the thread specified in AttachAllInThread()
|
|
// function that was called before
|
|
BOOL DetachAllInThread(BOOL bRedraw=TRUE);
|
|
|
|
|
|
// --- In : pWnd - pointer to created window
|
|
// --- Out :
|
|
// --- Returns: pointer to created COXCaptionPainter object if pWnd was
|
|
// successfully hooked, otherwise NULL
|
|
// --- Effect : Creates COXCaptionPainter object for specified window
|
|
// and attaches the specified window to it. Refer to the
|
|
// documentation on COXCaptionPainter::Attach() for
|
|
// additional info.
|
|
//
|
|
COXCaptionPainter* Attach(CWnd* pWnd);
|
|
|
|
|
|
// --- In : pWnd - pointer to the attached window or NULL.
|
|
// If NULL is specified then all attached
|
|
// windows will be unhooked.
|
|
// bRedraw - if TRUE then the soon to be detached window(s)
|
|
// will be redrawn
|
|
// --- Out :
|
|
// --- Returns: TRUE if function succeeded, or FALSE otherwise
|
|
// --- Effect : Unhooks specified or all attached window(s).
|
|
BOOL Detach(const CWnd* pWnd=NULL, BOOL bRedraw=TRUE);
|
|
|
|
|
|
// --- In : pWnd - pointer to the attached window or NULL.
|
|
// If NULL is specified then all attached
|
|
// windows will be set to use specified
|
|
// caption info object.
|
|
// pCI - pointer to COXCaptionInfo object
|
|
// bActive - TRUE if you want to set COXCaptionInfo object
|
|
// for active state or FALSE - for inactive state.
|
|
// bRedraw - if TRUE then the attached window
|
|
// will be redrawn
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Sets caption properties
|
|
BOOL SetCaptionInfo(const CWnd* pWnd, COXCaptionInfo* pCI,
|
|
BOOL bActive, BOOL bRedraw=TRUE) const;
|
|
|
|
|
|
// --- In : pWnd - pointer to the attached window or NULL.
|
|
// If NULL is specified then all attached
|
|
// windows will be reset.
|
|
// bRedraw - if TRUE then the attached window
|
|
// will be redrawn
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Resets size of caption that will eventually cause
|
|
// rebuilding of bitmaps for active/inactive caption
|
|
BOOL Reset(CWnd* pWnd, BOOL bRedraw=TRUE) const;
|
|
|
|
|
|
// --- In : pWnd - pointer to the attached window
|
|
// --- Out :
|
|
// --- Returns: Pointer to COXCaptionPainter object that corresponds
|
|
// to the specified attached window if succeed or NULL
|
|
// otherwise
|
|
// --- Effect : Retrieves the pointer to COXCaptionPainter object that
|
|
// corresponds to the specified attached window.
|
|
COXCaptionPainter* GetPainter(const CWnd* pWnd) const;
|
|
|
|
|
|
// --- In : pWnd - pointer to the window
|
|
// --- Out :
|
|
// --- Returns: TRUE if specified window was hooked before using
|
|
// Attach function or FALSE otherwise
|
|
// --- Effect : Retrieves the flag that specifies whether the given
|
|
// window was attached before or not.
|
|
BOOL IsAttached(const CWnd* pWnd) const;
|
|
|
|
|
|
#ifndef OXCP_NO_SAVESTATE
|
|
// Save to and load from registry (or *.ini file) state of caption
|
|
// These functions require using COXRegistryValFile class. If you
|
|
// are not going to use them then you can include in your stdafx.h
|
|
// file next code:
|
|
//
|
|
// #define OXCP_NO_SAVESTATE
|
|
//
|
|
// --- In : pWnd - pointer to the attached window or NULL.
|
|
// If NULL is specified then all attached
|
|
// windows will be reset.
|
|
// lpszProfileName - name of .ini file or hive in registry where
|
|
// all information about COXCaptionPainter
|
|
// was saved.
|
|
// bApply - if equals TRUE then COXCaptionPainter will be
|
|
// to redraw caption.
|
|
//
|
|
// --- Out :
|
|
// --- Returns: TRUE if succeeds, or FALSE otherwise.
|
|
// --- Effect : Loads COXCaptionPainter state from registry or *.ini file
|
|
BOOL LoadState(const CWnd* pWnd, LPCTSTR lpszProfileName, BOOL bApply=TRUE);
|
|
#endif // OXCP_NO_SAVESTATE
|
|
|
|
inline BOOL IsAttachedAllInThread() const { return (m_dwThreadID!=NULL); }
|
|
inline DWORD GetAttachedThread() const { return m_dwThreadID; }
|
|
inline HHOOK GetSavedGetMessageHookProc() const {
|
|
return m_pfnOldGetMessageHookProc;
|
|
}
|
|
inline HHOOK GetSavedCBTHookProc() const { return m_pfnOldCBTHookProc; }
|
|
static HHOOK GetOriginalCBTHookProc() {
|
|
return COXCaptionPainterOrganizer::m_pfnOriginalCBTHookProc;
|
|
}
|
|
static HHOOK GetOriginalGetMessageHookProc() {
|
|
return COXCaptionPainterOrganizer::m_pfnOriginalGetMessageHookProc;
|
|
}
|
|
|
|
inline COXCaptionPainter* GetFirstPainter(POSITION& pos) const {
|
|
pos=m_arrAttachedWnd.GetStartPosition();
|
|
HWND hWnd=NULL;
|
|
COXCaptionPainter* pPainter=NULL;
|
|
while(pos!=NULL)
|
|
{
|
|
m_arrAttachedWnd.GetNextAssoc(pos,hWnd,pPainter);
|
|
if(::IsWindow(hWnd))
|
|
{
|
|
ASSERT(pPainter!=NULL);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
pPainter=NULL;
|
|
}
|
|
}
|
|
return pPainter;
|
|
}
|
|
inline COXCaptionPainter* GetNextPainter(POSITION& pos) const {
|
|
if(pos==NULL)
|
|
return NULL;
|
|
HWND hWnd=NULL;
|
|
COXCaptionPainter* pPainter=NULL;
|
|
while(pos!=NULL)
|
|
{
|
|
m_arrAttachedWnd.GetNextAssoc(pos,hWnd,pPainter);
|
|
if(::IsWindow(hWnd))
|
|
{
|
|
ASSERT(pPainter!=NULL);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
pPainter=NULL;
|
|
}
|
|
}
|
|
return pPainter;
|
|
}
|
|
|
|
void AttachAllWindows(HWND hWndStartFrom);
|
|
|
|
public:
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns:
|
|
// --- Effect : Destructs the object
|
|
virtual ~COXCaptionPainterOrganizer();
|
|
|
|
public:
|
|
// map of all organizers that has been created to handle caption painting
|
|
// for all windows created by particular thread
|
|
static CMap<DWORD,DWORD,COXCaptionPainterOrganizer*,
|
|
COXCaptionPainterOrganizer*> m_arrThreadOrganizers;
|
|
|
|
protected:
|
|
// map of all attached windows and associated COXCaptionPainter objects
|
|
CMap<HWND,HWND,COXCaptionPainter*,COXCaptionPainter*> m_arrAttachedWnd;
|
|
// array of all used COXCaptionPainter objects
|
|
CArray<COXCaptionPainter*,COXCaptionPainter*> m_arrUsedPainters;
|
|
|
|
// ID of the attached thread
|
|
DWORD m_dwThreadID;
|
|
// handle of the old CBT hook procedure
|
|
HHOOK m_pfnOldCBTHookProc;
|
|
// handle of the original CBT hook procedure
|
|
static HHOOK m_pfnOriginalCBTHookProc;
|
|
|
|
// handle of the old GetMessage hook procedure
|
|
HHOOK m_pfnOldGetMessageHookProc;
|
|
// handle of the original GetMessage hook procedure
|
|
static HHOOK m_pfnOriginalGetMessageHookProc;
|
|
|
|
|
|
// hook procedure for CBT
|
|
static LRESULT CALLBACK CaptionPainterCBTHookProc(int nCode,
|
|
WPARAM wParam, LPARAM lParam);
|
|
|
|
// hook procedure for CBT
|
|
static LRESULT CALLBACK CaptionPainterGetMessageHookProc(int nCode,
|
|
WPARAM wParam, LPARAM lParam);
|
|
|
|
// callback for enumerating topmost windows
|
|
static BOOL CALLBACK EnumThreadWindows(HWND hWnd, LPARAM lParam);
|
|
};
|
|
|
|
#endif // _CAPTIONPAINTER_H
|
|
|