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

📄 rebar.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
	    lpBand->fDraw &= ~NTF_INVALIDATE;
	    work = lpBand->rcBand;
	    if (lpBand->fDraw & DRAW_RIGHTSEP) work.bottom += SEP_WIDTH_SIZE;
	    if (lpBand->fDraw & DRAW_BOTTOMSEP) work.right += SEP_WIDTH_SIZE;
	    InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
	}

    }
}


static VOID
REBAR_ForceResize (REBAR_INFO *infoPtr)
     /* Function: This changes the size of the REBAR window to that */
     /*  calculated by REBAR_Layout.                                */
{
    RECT rc;
    INT x, y, width, height;
    INT xedge = GetSystemMetrics(SM_CXEDGE);
    INT yedge = GetSystemMetrics(SM_CYEDGE);

    GetClientRect (infoPtr->hwndSelf, &rc);

    TRACE( " old [%d x %d], new [%d x %d], client [%d x %d]\n",
	   infoPtr->oldSize.cx, infoPtr->oldSize.cy,
	   infoPtr->calcSize.cx, infoPtr->calcSize.cy,
	   rc.right, rc.bottom);

    /* If we need to shrink client, then skip size test */
    if ((infoPtr->calcSize.cy >= rc.bottom) &&
	(infoPtr->calcSize.cx >= rc.right)) {

	/* if size did not change then skip process */
	if ((infoPtr->oldSize.cx == infoPtr->calcSize.cx) &&
	    (infoPtr->oldSize.cy == infoPtr->calcSize.cy) &&
	    !(infoPtr->fStatus & RESIZE_ANYHOW))
	    {
		TRACE("skipping reset\n");
		return;
	    }
    }

    infoPtr->fStatus &= ~RESIZE_ANYHOW;
    /* Set flag to ignore next WM_SIZE message */
    infoPtr->fStatus |= AUTO_RESIZE;

    width = 0;
    height = 0;
    x = 0;
    y = 0;

    if (infoPtr->dwStyle & WS_BORDER) {
	width = 2 * xedge;
	height = 2 * yedge;
    }

    if (!(infoPtr->dwStyle & CCS_NOPARENTALIGN)) {
	INT mode = infoPtr->dwStyle & (CCS_VERT | CCS_TOP | CCS_BOTTOM);
	RECT rcPcl;

	GetClientRect(GetParent(infoPtr->hwndSelf), &rcPcl);
	switch (mode) {
	case CCS_TOP:
	    /* _TOP sets width to parents width */
	    width += (rcPcl.right - rcPcl.left);
	    height += infoPtr->calcSize.cy;
	    x += ((infoPtr->dwStyle & WS_BORDER) ? -xedge : 0);
	    y += ((infoPtr->dwStyle & WS_BORDER) ? -yedge : 0);
	    y += ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER);
	    break;
	case CCS_BOTTOM:
	    /* FIXME: wrong wrong wrong */
	    /* _BOTTOM sets width to parents width */
	    width += (rcPcl.right - rcPcl.left);
	    height += infoPtr->calcSize.cy;
      	    x += -xedge;
	    y = rcPcl.bottom - height + 1;
	    break;
	case CCS_LEFT:
	    /* _LEFT sets height to parents height */
	    width += infoPtr->calcSize.cx;
	    height += (rcPcl.bottom - rcPcl.top);
	    x += ((infoPtr->dwStyle & WS_BORDER) ? -xedge : 0);
	    x += ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER);
	    y += ((infoPtr->dwStyle & WS_BORDER) ? -yedge : 0);
	    break;
	case CCS_RIGHT:
	    /* FIXME: wrong wrong wrong */
	    /* _RIGHT sets height to parents height */
	    width += infoPtr->calcSize.cx;
	    height += (rcPcl.bottom - rcPcl.top);
	    x = rcPcl.right - width + 1;
      	    y = -yedge;
	    break;
	default:
	    width += infoPtr->calcSize.cx;
	    height += infoPtr->calcSize.cy;
	}
    }
    else {
	width += infoPtr->calcSize.cx;
	height += infoPtr->calcSize.cy;
	x = infoPtr->origin.x;
	y = infoPtr->origin.y;
    }

    TRACE("hwnd %p, style=%08x, setting at (%d,%d) for (%d,%d)\n",
	infoPtr->hwndSelf, infoPtr->dwStyle,
	x, y, width, height);
    SetWindowPos (infoPtr->hwndSelf, 0, x, y, width, height,
		    SWP_NOZORDER);
    infoPtr->fStatus &= ~AUTO_RESIZE;
}


static VOID
REBAR_MoveChildWindows (REBAR_INFO *infoPtr, UINT start, UINT endplus)
{
    static const WCHAR strComboBox[] = { 'C','o','m','b','o','B','o','x',0 };
    REBAR_BAND *lpBand;
    WCHAR szClassName[40];
    UINT i;
    NMREBARCHILDSIZE  rbcz;
    NMHDR heightchange;
    HDWP deferpos;

    if (!(deferpos = BeginDeferWindowPos(infoPtr->uNumBands)))
        ERR("BeginDeferWindowPos returned NULL\n");

    for (i = start; i < endplus; i++) {
	lpBand = &infoPtr->bands[i];

	if (HIDDENBAND(lpBand)) continue;
	if (lpBand->hwndChild) {
	    TRACE("hwndChild = %p\n", lpBand->hwndChild);

	    /* Always geterate the RBN_CHILDSIZE even it child
		   did not change */
	    rbcz.uBand = i;
	    rbcz.wID = lpBand->wID;
	    rbcz.rcChild = lpBand->rcChild;
	    rbcz.rcBand = lpBand->rcBand;
	    if (infoPtr->dwStyle & CCS_VERT)
		rbcz.rcBand.top += lpBand->cxHeader;
	    else
		rbcz.rcBand.left += lpBand->cxHeader;
	    REBAR_Notify ((NMHDR *)&rbcz, infoPtr, RBN_CHILDSIZE);
	    if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
		TRACE("Child rect changed by NOTIFY for band %u\n", i);
		TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
		      lpBand->rcChild.left, lpBand->rcChild.top,
		      lpBand->rcChild.right, lpBand->rcChild.bottom,
		      rbcz.rcChild.left, rbcz.rcChild.top,
		      rbcz.rcChild.right, rbcz.rcChild.bottom);
		lpBand->rcChild = rbcz.rcChild;  /* *** ??? */
	    }

	    /* native (IE4 in "Favorites" frame **1) does:
	     *   SetRect (&rc, -1, -1, -1, -1)
	     *   EqualRect (&rc,band->rc???)
	     *   if ret==0
	     *     CopyRect (band->rc????, &rc)
	     *     set flag outside of loop
	     */

	    GetClassNameW (lpBand->hwndChild, szClassName, sizeof(szClassName)/sizeof(szClassName[0]));
	    if (!lstrcmpW (szClassName, strComboBox) ||
		!lstrcmpW (szClassName, WC_COMBOBOXEXW)) {
		INT nEditHeight, yPos;
		RECT rc;

		/* special placement code for combo or comboex box */


		/* get size of edit line */
		GetWindowRect (lpBand->hwndChild, &rc);
		nEditHeight = rc.bottom - rc.top;
		yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;

		/* center combo box inside child area */
		TRACE("moving child (Combo(Ex)) %p to (%d,%d) for (%d,%d)\n",
		      lpBand->hwndChild,
		      lpBand->rcChild.left, yPos,
		      lpBand->rcChild.right - lpBand->rcChild.left,
		      nEditHeight);
		deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
					   lpBand->rcChild.left,
					   /*lpBand->rcChild.top*/ yPos,
					   lpBand->rcChild.right - lpBand->rcChild.left,
					   nEditHeight,
					   SWP_NOZORDER);
		if (!deferpos)
		    ERR("DeferWindowPos returned NULL\n");
	    }
	    else {
		TRACE("moving child (Other) %p to (%d,%d) for (%d,%d)\n",
		      lpBand->hwndChild,
		      lpBand->rcChild.left, lpBand->rcChild.top,
		      lpBand->rcChild.right - lpBand->rcChild.left,
		      lpBand->rcChild.bottom - lpBand->rcChild.top);
		deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
					   lpBand->rcChild.left,
					   lpBand->rcChild.top,
					   lpBand->rcChild.right - lpBand->rcChild.left,
					   lpBand->rcChild.bottom - lpBand->rcChild.top,
					   SWP_NOZORDER);
		if (!deferpos)
		    ERR("DeferWindowPos returned NULL\n");
	    }
	}
    }
    if (!EndDeferWindowPos(deferpos))
        ERR("EndDeferWindowPos returned NULL\n");

    if (infoPtr->DoRedraw)
	UpdateWindow (infoPtr->hwndSelf);

    if (infoPtr->fStatus & NTF_HGHTCHG) {
        infoPtr->fStatus &= ~NTF_HGHTCHG;
        /*
         * We need to force a resize here, because some applications
         * try to get the rebar size during processing of the 
         * RBN_HEIGHTCHANGE notification.
         */
        REBAR_ForceResize (infoPtr);
        REBAR_Notify (&heightchange, infoPtr, RBN_HEIGHTCHANGE);
    }

    /* native (from **1 above) does:
     *      UpdateWindow(rebar)
     *      REBAR_ForceResize
     *      RBN_HEIGHTCHANGE if necessary
     *      if ret from any EqualRect was 0
     *         Goto "BeginDeferWindowPos"
     */

}


static VOID
REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
     /* Function: This routine is resposible for laying out all */
     /*  the bands in a rebar. It assigns each band to a row and*/
     /*  determines when to start a new row.                    */
{
    REBAR_BAND *lpBand, *prevBand;
    RECT rcClient, rcAdj;
    INT initx, inity, x, y, cx, cxsep, mmcy, mcy, clientcx, clientcy;
    INT adjcx, adjcy, row, rightx, bottomy, origheight;
    UINT i, j, rowstart, origrows, cntonrow;
    BOOL dobreak;

    if (!(infoPtr->fStatus & BAND_NEEDS_LAYOUT)) {
	TRACE("no layout done. No band changed.\n");
	REBAR_DumpBand (infoPtr);
	return;
    }
    infoPtr->fStatus &= ~BAND_NEEDS_LAYOUT;
    if (!infoPtr->DoRedraw) infoPtr->fStatus |= BAND_NEEDS_REDRAW;

    GetClientRect (infoPtr->hwndSelf, &rcClient);
    TRACE("Client is (%d,%d)-(%d,%d)\n",
	  rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);

    if (lpRect) {
	rcAdj = *lpRect;
	TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
	      rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
    }
    else {
        CopyRect (&rcAdj, &rcClient);
    }

    clientcx = rcClient.right - rcClient.left;
    clientcy = rcClient.bottom - rcClient.top;
    adjcx = rcAdj.right - rcAdj.left;
    adjcy = rcAdj.bottom - rcAdj.top;
    if (resetclient) {
        TRACE("window client rect will be set to adj rect\n");
        clientcx = adjcx;
        clientcy = adjcy;
    }

    if (!infoPtr->DoRedraw && (clientcx == 0) && (clientcy == 0)) {
	ERR("no redraw and client is zero, skip layout\n");
	infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
	return;
    }

    /* save height of original control */
    if (infoPtr->dwStyle & CCS_VERT)
        origheight = infoPtr->calcSize.cx;
    else
        origheight = infoPtr->calcSize.cy;
    origrows = infoPtr->uNumRows;

    initx = 0;
    inity = 0;

    /* ******* Start Phase 1 - all bands on row at minimum size ******* */

    TRACE("band loop constants, clientcx=%d, clientcy=%d, adjcx=%d, adjcy=%d\n",
	  clientcx, clientcy, adjcx, adjcy);
    x = initx;
    y = inity;
    row = 0;
    cx = 0;
    mcy = 0;
    rowstart = 0;
    prevBand = NULL;
    cntonrow = 0;

    for (i = 0; i < infoPtr->uNumBands; i++) {
	lpBand = &infoPtr->bands[i];
	lpBand->fDraw = 0;
	lpBand->iRow = row;

	SetRectEmpty(&lpBand->rcChevron);

	if (HIDDENBAND(lpBand)) continue;

	lpBand->rcoldBand = lpBand->rcBand;

	/* Set the offset of the child window */
	if ((lpBand->fMask & RBBIM_CHILD) &&
	    !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
	    lpBand->offChild.cx = ((lpBand->fStyle & RBBS_CHILDEDGE) ? 4 : 0);
	}
	lpBand->offChild.cy = ((lpBand->fStyle & RBBS_CHILDEDGE) ? 2 : 0);

	/* separator from previous band */
	cxsep = (cntonrow == 0) ? 0 : SEP_WIDTH;
	cx = lpBand->lcx;

        /* In native, 0 as one of the coordinates means no limit */
	if (infoPtr->dwStyle & CCS_VERT)
	    dobreak = (adjcy && (y + cx + cxsep > adjcy));
        else
	    dobreak = (adjcx && (x + cx + cxsep > adjcx));

	/* This is the check for whether we need to start a new row */
	if ( ( (lpBand->fStyle & RBBS_BREAK) && (i != 0) ) ||
	     ( ((infoPtr->dwStyle & CCS_VERT) ? (y != 0) : (x != 0)) && dobreak)) {

	    for (j = rowstart; j < i; j++) {
		REBAR_BAND *lpB;
		lpB = &infoPtr->bands[j];
		if (infoPtr->dwStyle & CCS_VERT) {
		    lpB->rcBand.right  = lpB->rcBand.left + mcy;
		}
		else {
		    lpB->rcBand.bottom = lpB->rcBand.top + mcy;
		}
	    }

	    TRACE("P1 Spliting to new row %d on band %u\n", row+1, i);
	    if (infoPtr->dwStyle & CCS_VERT) {
		y = inity;
		x += (mcy + SEP_WIDTH);
	    }
	    else {
		x = initx;
		y += (mcy + SEP_WIDTH);
	    }

	    mcy = 0;
	    cxsep = 0;
	    row++;
	    lpBand->iRow = row;
	    prevBand = NULL;
	    rowstart = i;
	    cntonrow = 0;
	}

	if (mcy < lpBand->lcy + REBARSPACE(lpBand))
	    mcy = lpBand->lcy + REBARSPACE(lpBand);

	/* if boundary rect specified then limit mcy */
	if (lpRect) {
	    if (infoPtr->dwStyle & CCS_VERT) {
	        if (adjcx && (x+mcy > adjcx)) {
		    mcy = adjcx - x;
		    TRACE("P1 row %u limiting mcy=%d, adjcx=%d, x=%d\n",
			  i, mcy, adjcx, x);
		}

⌨️ 快捷键说明

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