⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rebar.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Rebar control
 *
 * Copyright 1998, 1999 Eric Kohl
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES
 *
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on Oct. 19, 2004, by Robert Shearman.
 * 
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features or bugs please note them below.
 *
 * TODO
 *   Styles:
 *   - RBS_DBLCLKTOGGLE
 *   - RBS_FIXEDORDER
 *   - RBS_REGISTERDROP
 *   - RBS_TOOLTIPS
 *   - CCS_NORESIZE
 *   - CCS_NOMOVEX
 *   - CCS_NOMOVEY
 *   Messages:
 *   - RB_BEGINDRAG
 *   - RB_DRAGMOVE
 *   - RB_ENDDRAG
 *   - RB_GETBANDMARGINS
 *   - RB_GETCOLORSCHEME
 *   - RB_GETDROPTARGET
 *   - RB_GETPALETTE
 *   - RB_SETCOLORSCHEME
 *   - RB_SETPALETTE
 *   - RB_SETTOOLTIPS
 *   - WM_CHARTOITEM
 *   - WM_LBUTTONDBLCLK
 *   - WM_MEASUREITEM
 *   - WM_PALETTECHANGED
 *   - WM_QUERYNEWPALETTE
 *   - WM_RBUTTONDOWN
 *   - WM_RBUTTONUP
 *   - WM_SYSCOLORCHANGE
 *   - WM_VKEYTOITEM
 *   - WM_WININICHANGE
 *   Notifications:
 *   - NM_HCHITTEST
 *   - NM_RELEASEDCAPTURE
 *   - RBN_AUTOBREAK
 *   - RBN_GETOBJECT
 *   - RBN_MINMAX
 *   Band styles:
 *   - RBBS_FIXEDBMP
 *   Native uses (on each draw!!) SM_CYBORDER (or SM_CXBORDER for CCS_VERT)
 *   to set the size of the separator width (the value SEP_WIDTH_SIZE
 *   in here). Should be fixed!!
 */

/*
 * Testing: set to 1 to make background brush *always* green
 */
#define GLATESTING 0

/*
 *
 * 2.  At "FIXME:  problem # 2" WinRAR:
 *   if "#if 1" then last band draws in separate row
 *   if "#if 0" then last band draws in previous row *** just like native ***
 *
 */
#define PROBLEM2 0

/*
 * 3. REBAR_MoveChildWindows should have a loop because more than
 *    one pass is made (together with the RBN_CHILDSIZEs) is made on
 *    at least RB_INSERTBAND
 */

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/unicode.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "uxtheme.h"
#include "tmschema.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(rebar);

typedef struct
{
    UINT    fStyle;
    UINT    fMask;
    COLORREF  clrFore;
    COLORREF  clrBack;
    INT     iImage;
    HWND    hwndChild;
    UINT    cxMinChild;     /* valid if _CHILDSIZE */
    UINT    cyMinChild;     /* valid if _CHILDSIZE */
    UINT    cx;             /* valid if _SIZE */
    HBITMAP hbmBack;
    UINT    wID;
    UINT    cyChild;        /* valid if _CHILDSIZE */
    UINT    cyMaxChild;     /* valid if _CHILDSIZE */
    UINT    cyIntegral;     /* valid if _CHILDSIZE */
    UINT    cxIdeal;
    LPARAM    lParam;
    UINT    cxHeader;

    UINT    lcx;            /* minimum cx for band */
    UINT    ccx;            /* current cx for band */
    UINT    hcx;            /* maximum cx for band */
    UINT    lcy;            /* minimum cy for band */
    UINT    ccy;            /* current cy for band */
    UINT    hcy;            /* maximum cy for band */

    SIZE    offChild;       /* x,y offset if child is not FIXEDSIZE */
    UINT    uMinHeight;
    INT     iRow;           /* zero-based index of the row this band assigned to */
    UINT    fStatus;        /* status flags, reset only by _Validate */
    UINT    fDraw;          /* drawing flags, reset only by _Layout */
    UINT    uCDret;         /* last return from NM_CUSTOMDRAW */
    RECT    rcoldBand;      /* previous calculated band rectangle */
    RECT    rcBand;         /* calculated band rectangle */
    RECT    rcGripper;      /* calculated gripper rectangle */
    RECT    rcCapImage;     /* calculated caption image rectangle */
    RECT    rcCapText;      /* calculated caption text rectangle */
    RECT    rcChild;        /* calculated child rectangle */
    RECT    rcChevron;      /* calculated chevron rectangle */

    LPWSTR    lpText;
    HWND    hwndPrevParent;
} REBAR_BAND;

/* fStatus flags */
#define HAS_GRIPPER    0x00000001
#define HAS_IMAGE      0x00000002
#define HAS_TEXT       0x00000004

/* fDraw flags */
#define DRAW_GRIPPER    0x00000001
#define DRAW_IMAGE      0x00000002
#define DRAW_TEXT       0x00000004
#define DRAW_RIGHTSEP   0x00000010
#define DRAW_BOTTOMSEP  0x00000020
#define DRAW_CHEVRONHOT 0x00000040
#define DRAW_CHEVRONPUSHED 0x00000080
#define DRAW_LAST_IN_ROW   0x00000100
#define DRAW_FIRST_IN_ROW  0x00000200
#define NTF_INVALIDATE  0x01000000

typedef struct
{
    COLORREF   clrBk;       /* background color */
    COLORREF   clrText;     /* text color */
    COLORREF   clrBtnText;  /* system color for BTNTEXT */
    COLORREF   clrBtnFace;  /* system color for BTNFACE */
    HIMAGELIST himl;        /* handle to imagelist */
    UINT     uNumBands;   /* # of bands in rebar (first=0, last=uNumBands-1 */
    UINT     uNumRows;    /* # of rows of bands (first=1, last=uNumRows */
    HWND     hwndSelf;    /* handle of REBAR window itself */
    HWND     hwndToolTip; /* handle to the tool tip control */
    HWND     hwndNotify;  /* notification window (parent) */
    HFONT    hDefaultFont;
    HFONT    hFont;       /* handle to the rebar's font */
    SIZE     imageSize;   /* image size (image list) */
    DWORD    dwStyle;     /* window style */
    DWORD    orgStyle;    /* original style (dwStyle may change) */
    SIZE     calcSize;    /* calculated rebar size */
    SIZE     oldSize;     /* previous calculated rebar size */
    BOOL     bUnicode;    /* TRUE if parent wants notify in W format */
    BOOL     DoRedraw;    /* TRUE to acutally draw bands */
    UINT     fStatus;     /* Status flags (see below)  */
    HCURSOR  hcurArrow;   /* handle to the arrow cursor */
    HCURSOR  hcurHorz;    /* handle to the EW cursor */
    HCURSOR  hcurVert;    /* handle to the NS cursor */
    HCURSOR  hcurDrag;    /* handle to the drag cursor */
    INT      iVersion;    /* version number */
    POINT    dragStart;   /* x,y of button down */
    POINT    dragNow;     /* x,y of this MouseMove */
    INT      iOldBand;    /* last band that had the mouse cursor over it */
    INT      ihitoffset;  /* offset of hotspot from gripper.left */
    POINT    origin;      /* left/upper corner of client */
    INT      ichevronhotBand; /* last band that had a hot chevron */
    INT      iGrabbedBand;/* band number of band whose gripper was grabbed */

    REBAR_BAND *bands;      /* pointer to the array of rebar bands */
} REBAR_INFO;

/* fStatus flags */
#define BEGIN_DRAG_ISSUED   0x00000001
#define AUTO_RESIZE         0x00000002
#define RESIZE_ANYHOW       0x00000004
#define NTF_HGHTCHG         0x00000008
#define BAND_NEEDS_LAYOUT   0x00000010
#define BAND_NEEDS_REDRAW   0x00000020
#define CREATE_RUNNING      0x00000040

/* ----   REBAR layout constants. Mostly determined by        ---- */
/* ----   experiment on WIN 98.                               ---- */

/* Width (or height) of separators between bands (either horz. or  */
/* vert.). True only if RBS_BANDBORDERS is set                     */
#define SEP_WIDTH_SIZE  2
#define SEP_WIDTH       ((infoPtr->dwStyle & RBS_BANDBORDERS) ? SEP_WIDTH_SIZE : 0)

/* Blank (background color) space between Gripper (if present)     */
/* and next item (image, text, or window). Always present          */
#define REBAR_ALWAYS_SPACE  4

/* Blank (background color) space after Image (if present).        */
#define REBAR_POST_IMAGE  2

/* Blank (background color) space after Text (if present).         */
#define REBAR_POST_TEXT  4

/* Height of vertical gripper in a CCS_VERT rebar.                 */
#define GRIPPER_HEIGHT  16

/* Blank (background color) space before Gripper (if present).     */
#define REBAR_PRE_GRIPPER   2

/* Width (of normal vertical gripper) or height (of horz. gripper) */
/* if present.                                                     */
#define GRIPPER_WIDTH  3

/* Width of the chevron button if present */
#define CHEVRON_WIDTH  10

/* Height of divider for Rebar if not disabled (CCS_NODIVIDER)     */
/* either top or bottom                                            */
#define REBAR_DIVIDER  2

/* minimium vertical height of a normal bar                        */
/*   or minimum width of a CCS_VERT bar - from experiment on Win2k */
#define REBAR_MINSIZE  23

/* This is the increment that is used over the band height         */
#define REBARSPACE(a)     ((a->fStyle & RBBS_CHILDEDGE) ? 2*REBAR_DIVIDER : 0)

/* ----   End of REBAR layout constants.                      ---- */

#define RB_GETBANDINFO_OLD (WM_USER+5) /* obsoleted after IE3, but we have to support it anyway */

/*  The following 6 defines return the proper rcBand element       */
/*  depending on whether CCS_VERT was set.                         */
#define rcBlt(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.top : b->rcBand.left)
#define rcBrb(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.bottom : b->rcBand.right)
#define rcBw(b)  ((infoPtr->dwStyle & CCS_VERT) ? (b->rcBand.bottom - b->rcBand.top) : \
		  (b->rcBand.right - b->rcBand.left))
#define ircBlt(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.left : b->rcBand.top)
#define ircBrb(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.right : b->rcBand.bottom)
#define ircBw(b)  ((infoPtr->dwStyle & CCS_VERT) ? (b->rcBand.right - b->rcBand.left) : \
		  (b->rcBand.bottom - b->rcBand.top))

/*  The following define determines if a given band is hidden      */
#define HIDDENBAND(a)  (((a)->fStyle & RBBS_HIDDEN) ||   \
                        ((infoPtr->dwStyle & CCS_VERT) &&         \
                         ((a)->fStyle & RBBS_NOVERT)))

/*  The following defines adjust the right or left end of a rectangle */
#define READJ(b,i) do { if(infoPtr->dwStyle & CCS_VERT) b->rcBand.bottom+=(i); \
                    else b->rcBand.right += (i); } while(0)
#define LEADJ(b,i) do { if(infoPtr->dwStyle & CCS_VERT) b->rcBand.top+=(i); \
                    else b->rcBand.left += (i); } while(0)


#define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongPtrW (hwnd, 0))

static LRESULT REBAR_NotifyFormat(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam);


/* "constant values" retrieved when DLL was initialized    */
/* FIXME we do this when the classes are registered.       */
static UINT mindragx = 0;
static UINT mindragy = 0;

static const char *band_stylename[] = {
    "RBBS_BREAK",              /* 0001 */
    "RBBS_FIXEDSIZE",          /* 0002 */
    "RBBS_CHILDEDGE",          /* 0004 */
    "RBBS_HIDDEN",             /* 0008 */
    "RBBS_NOVERT",             /* 0010 */
    "RBBS_FIXEDBMP",           /* 0020 */
    "RBBS_VARIABLEHEIGHT",     /* 0040 */
    "RBBS_GRIPPERALWAYS",      /* 0080 */
    "RBBS_NOGRIPPER",          /* 0100 */
    NULL };

static const char *band_maskname[] = {
    "RBBIM_STYLE",         /*    0x00000001 */
    "RBBIM_COLORS",        /*    0x00000002 */
    "RBBIM_TEXT",          /*    0x00000004 */
    "RBBIM_IMAGE",         /*    0x00000008 */
    "RBBIM_CHILD",         /*    0x00000010 */
    "RBBIM_CHILDSIZE",     /*    0x00000020 */
    "RBBIM_SIZE",          /*    0x00000040 */
    "RBBIM_BACKGROUND",    /*    0x00000080 */
    "RBBIM_ID",            /*    0x00000100 */
    "RBBIM_IDEALSIZE",     /*    0x00000200 */
    "RBBIM_LPARAM",        /*    0x00000400 */
    "RBBIM_HEADERSIZE",    /*    0x00000800 */
    NULL };


static CHAR line[200];

static const WCHAR themeClass[] = { 'R','e','b','a','r',0 };

static CHAR *
REBAR_FmtStyle( UINT style)
{
    INT i = 0;

    *line = 0;
    while (band_stylename[i]) {
	if (style & (1<<i)) {
	    if (*line != 0) strcat(line, " | ");
	    strcat(line, band_stylename[i]);
	}
	i++;
    }
    return line;
}


static CHAR *
REBAR_FmtMask( UINT mask)
{
    INT i = 0;

    *line = 0;
    while (band_maskname[i]) {
	if (mask & (1<<i)) {
	    if (*line != 0) strcat(line, " | ");
	    strcat(line, band_maskname[i]);
	}
	i++;
    }
    return line;
}


static VOID
REBAR_DumpBandInfo( LPREBARBANDINFOA pB)
{
    if( !TRACE_ON(rebar) ) return;
    TRACE("band info: ");
    if (pB->fMask & RBBIM_ID)
        TRACE("ID=%u, ", pB->wID);
    TRACE("size=%u, child=%p", pB->cbSize, pB->hwndChild);
    if (pB->fMask & RBBIM_COLORS)
        TRACE(", clrF=0x%06x, clrB=0x%06x", pB->clrFore, pB->clrBack);
    TRACE("\n");

    TRACE("band info: mask=0x%08x (%s)\n", pB->fMask, REBAR_FmtMask(pB->fMask));
    if (pB->fMask & RBBIM_STYLE)
	TRACE("band info: style=0x%08x (%s)\n", pB->fStyle, REBAR_FmtStyle(pB->fStyle));
    if (pB->fMask & (RBBIM_SIZE | RBBIM_IDEALSIZE | RBBIM_HEADERSIZE | RBBIM_LPARAM )) {
	TRACE("band info:");
	if (pB->fMask & RBBIM_SIZE)
	    TRACE(" cx=%u", pB->cx);
	if (pB->fMask & RBBIM_IDEALSIZE)
	    TRACE(" xIdeal=%u", pB->cxIdeal);
	if (pB->fMask & RBBIM_HEADERSIZE)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -