예제 #1
0
    // Calculates tab's elements, based on its width and height.
    // Generates a GraphicsPath, which is used for painting the tab, etc.
    bool Reshape(int dx, int dy) {
        dx--;
        if (width == dx && height == dy)
            return false;
        width = dx;
        height = dy;

        GraphicsPath shape;
        // define tab's body
        shape.AddRectangle(Rect(0, 0, width, height));
        shape.SetMarker();

        // define "x"'s circle
        int c = int((float)height * 0.78f + 0.5f); // size of bounding square for the circle
        int maxC = DpiScaleX(hwnd, 17);
        if (height > maxC) {
            c = DpiScaleX(hwnd, 17);
        }
        Point p(width - c - DpiScaleX(hwnd, 3), (height - c) / 2); // circle's position
        shape.AddEllipse(p.X, p.Y, c, c);
        shape.SetMarker();
        // define "x"
        int o = int((float)c * 0.286f + 0.5f); // "x"'s offset
        shape.AddLine(p.X + o, p.Y + o, p.X + c - o, p.Y + c - o);
        shape.StartFigure();
        shape.AddLine(p.X + c - o, p.Y + o, p.X + o, p.Y + c - o);
        shape.SetMarker();

        delete data;
        data = new PathData();
        shape.GetPathData(data);
        return true;
    }
예제 #2
0
static void CalcCloseButtonPos(LabelWithCloseWnd *w, int dx, int dy) {
    int btnDx = DpiScaleX(w->hwnd, CLOSE_BTN_DX);
    int btnDy = DpiScaleY(w->hwnd, CLOSE_BTN_DY);
    int x = dx - btnDx - DpiScaleX(w->hwnd, w->padX);
    int y = 0;
    if (dy > btnDy) {
        y = (dy - btnDy) / 2;
    }
    w->closeBtnPos = RectI(x, y, btnDx, btnDy);
}
예제 #3
0
SizeI GetIdealSize(LabelWithCloseWnd *w) {
    WCHAR *s = win::GetText(w->hwnd);
    SizeI size = TextSizeInHwnd(w->hwnd, s);
    free(s);
    int btnDx = DpiScaleX(w->hwnd, CLOSE_BTN_DX);
    int btnDy = DpiScaleY(w->hwnd, CLOSE_BTN_DY);
    size.dx += btnDx;
    size.dx += DpiScaleX(w->hwnd, LABEL_BUTTON_SPACE_DX);
    size.dx += 2 * DpiScaleX(w->hwnd, w->padX);
    if (size.dy < btnDy) {
        size.dy = btnDy;
    }
    size.dy += 2 * DpiScaleY(w->hwnd, w->padY);
    return size;
}
예제 #4
0
static void PaintHDC(LabelWithCloseWnd *w, HDC hdc, const PAINTSTRUCT &ps) {
    HBRUSH br = CreateSolidBrush(w->bgCol);
    FillRect(hdc, &ps.rcPaint, br);

    ClientRect cr(w->hwnd);

    int x = DpiScaleX(w->hwnd, w->padX);
    int y = DpiScaleY(w->hwnd, w->padY);
    UINT opts = ETO_OPAQUE;
    if (IsRtl(w->hwnd)) {
        opts = opts | ETO_RTLREADING;
    }

    HGDIOBJ prevFont = nullptr;
    if (w->font) {
        prevFont = SelectObject(hdc, w->font);
    }
    SetTextColor(hdc, w->txtCol);
    SetBkColor(hdc, w->bgCol);

    WCHAR *s = win::GetText(w->hwnd);
    ExtTextOut(hdc, x, y, opts, nullptr, s, (UINT)str::Len(s), nullptr);
    free(s);

    // Text might be too long and invade close button area. We just re-paint
    // the background, which is not the pretties but works.
    // A better way would be to intelligently truncate text or shrink the font
    // size (within reason)
    x = w->closeBtnPos.x - DpiScaleX(w->hwnd, LABEL_BUTTON_SPACE_DX);
    RectI ri(x, 0, cr.dx - x, cr.dy);
    RECT r = ri.ToRECT();
    FillRect(hdc, &r, br);

    DrawCloseButton(hdc, w);
    DeleteObject(br);

    if (w->font) {
        SelectObject(hdc, prevFont);
    }
}
예제 #5
0
/* ツールバー作成
	@date @@@ 2002.01.03 YAZAKI m_tbMyButtonなどをCShareDataからCMenuDrawerへ移動したことによる修正。
	@date 2005.08.29 aroka ツールバーの折り返し
	@date 2006.06.17 ryoji ビジュアルスタイルが有効の場合はツールバーを Rebar に入れてサイズ変更時のちらつきを無くす
*/
void CMainToolBar::CreateToolBar( void )
{
	if( m_hwndToolBar )return;

	REBARINFO		rbi;
	REBARBANDINFO	rbBand;
	int				nFlag;
	TBBUTTON		tbb;
	int				i;
	int				nIdx;
	LONG_PTR		lToolType;
	nFlag = 0;

	// 2006.06.17 ryoji
	// Rebar ウィンドウの作成
	if( IsVisualStyle() ){	// ビジュアルスタイル有効
		m_hwndReBar = ::CreateWindowEx(
			WS_EX_TOOLWINDOW,
			REBARCLASSNAME, //レバーコントロール
			NULL,
			WS_CHILD/* | WS_VISIBLE*/ | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |	// 2007.03.08 ryoji WS_VISIBLE 除去
			RBS_BANDBORDERS | CCS_NODIVIDER,
			0, 0, 0, 0,
			m_pOwner->GetHwnd(),
			NULL,
			CEditApp::getInstance()->GetAppInstance(),
			NULL
		);

		if( NULL == m_hwndReBar ){
			TopWarningMessage( m_pOwner->GetHwnd(), LS(STR_ERR_DLGEDITWND04) );
			return;
		}

		if( GetDllShareData().m_Common.m_sToolBar.m_bToolBarIsFlat ){	/* フラットツールバーにする/しない */
			PreventVisualStyle( m_hwndReBar );	// ビジュアルスタイル非適用のフラットな Rebar にする
		}

		::ZeroMemory(&rbi, sizeof(rbi));
		rbi.cbSize = sizeof(rbi);
		Rebar_SetbarInfo(m_hwndReBar, &rbi);

		nFlag = CCS_NORESIZE | CCS_NODIVIDER | CCS_NOPARENTALIGN | TBSTYLE_FLAT;	// ツールバーへの追加スタイル
	}

	/* ツールバーウィンドウの作成 */
	m_hwndToolBar = ::CreateWindowEx(
		0,
		TOOLBARCLASSNAME,
		NULL,
		WS_CHILD/* | WS_VISIBLE*/ | WS_CLIPCHILDREN | /*WS_BORDER | */	// 2006.06.17 ryoji WS_CLIPCHILDREN 追加	// 2007.03.08 ryoji WS_VISIBLE 除去
/*		WS_EX_WINDOWEDGE| */
		TBSTYLE_TOOLTIPS |
//		TBSTYLE_WRAPABLE |
//		TBSTYLE_ALTDRAG |
//		CCS_ADJUSTABLE |
		nFlag,
		0, 0,
		0, 0,
		m_pOwner->GetHwnd(),
		(HMENU)ID_TOOLBAR,
		CEditApp::getInstance()->GetAppInstance(),
		NULL
	);
	if( NULL == m_hwndToolBar ){
		if( GetDllShareData().m_Common.m_sToolBar.m_bToolBarIsFlat ){	/* フラットツールバーにする/しない */
			GetDllShareData().m_Common.m_sToolBar.m_bToolBarIsFlat = FALSE;
		}
		TopWarningMessage( m_pOwner->GetHwnd(), LS(STR_ERR_DLGEDITWND05) );
		DestroyToolBar();	// 2006.06.17 ryoji
	}
	else{
		// 2006.09.06 ryoji ツールバーをサブクラス化する
		g_pOldToolBarWndProc = (WNDPROC)::SetWindowLongPtr(
			m_hwndToolBar,
			GWLP_WNDPROC,
			(LONG_PTR)ToolBarWndProc
		);

		Toolbar_SetButtonSize( m_hwndToolBar, DpiScaleX(22), DpiScaleY(22) );	// 2009.10.01 ryoji 高DPI対応スケーリング
		Toolbar_ButtonStructSize( m_hwndToolBar, sizeof(TBBUTTON) );
		//	Oct. 12, 2000 genta
		//	既に用意されているImage Listをアイコンとして登録
		m_pcIcons->SetToolBarImages( m_hwndToolBar );
		/* ツールバーにボタンを追加 */
		int count = 0;	//@@@ 2002.06.15 MIK
		int nToolBarButtonNum = 0;// 2005/8/29 aroka
		//	From Here 2005.08.29 aroka
		// はじめにツールバー構造体の配列を作っておく
		TBBUTTON *pTbbArr = new TBBUTTON[GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonNum];
		for( i = 0; i < GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonNum; ++i ){
			nIdx = GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonIdxArr[i];
			pTbbArr[nToolBarButtonNum] = m_pOwner->GetMenuDrawer().getButton(nIdx);
			// セパレータが続くときはひとつにまとめる
			// 折り返しボタンもTBSTYLE_SEP属性を持っているので
			// 折り返しの前のセパレータは全て削除される.
			if( (pTbbArr[nToolBarButtonNum].fsStyle & TBSTYLE_SEP) && (nToolBarButtonNum!=0)){
				if( (pTbbArr[nToolBarButtonNum-1].fsStyle & TBSTYLE_SEP) ){
					pTbbArr[nToolBarButtonNum-1] = pTbbArr[nToolBarButtonNum];
					nToolBarButtonNum--;
				}
			}
			// 仮想折返しボタンがきたら直前のボタンに折返し属性を付ける
			if( pTbbArr[nToolBarButtonNum].fsState & TBSTATE_WRAP ){
				if( nToolBarButtonNum!=0 ){
					pTbbArr[nToolBarButtonNum-1].fsState |= TBSTATE_WRAP;
				}
				continue;
			}
			nToolBarButtonNum++;
		}
		//	To Here 2005.08.29 aroka

		for( i = 0; i < nToolBarButtonNum; ++i ){
			tbb = pTbbArr[i];

			//@@@ 2002.06.15 MIK start
			switch( tbb.fsStyle )
			{
			case TBSTYLE_DROPDOWN:	//ドロップダウン
				//拡張スタイルに設定
				Toolbar_SetExtendedStyle( m_hwndToolBar, TBSTYLE_EX_DRAWDDARROWS );
				Toolbar_AddButtons( m_hwndToolBar, 1, &tbb );
				count++;
				break;

			case TBSTYLE_COMBOBOX:	//コンボボックス
				{
					RECT			rc;
					TBBUTTONINFO	tbi;
					TBBUTTON		my_tbb;
					LOGFONT		lf;

					switch( tbb.idCommand )
					{
					case F_SEARCH_BOX:
						if( m_hwndSearchBox )
						{
							break;
						}
						
						//セパレータ作る
						memset_raw( &my_tbb, 0, sizeof(my_tbb) );
						my_tbb.fsStyle   = TBSTYLE_BUTTON;  //ボタンにしないと描画が乱れる 2005/8/29 aroka
						my_tbb.idCommand = tbb.idCommand;	//同じIDにしておく
						if( tbb.fsState & TBSTATE_WRAP ){   //折り返し 2005/8/29 aroka
							my_tbb.fsState |=  TBSTATE_WRAP;
						}
						Toolbar_AddButtons( m_hwndToolBar, 1, &my_tbb );
						count++;

						//サイズを設定する
						tbi.cbSize = sizeof(tbi);
						tbi.dwMask = TBIF_SIZE;
						tbi.cx     = (WORD)DpiScaleX(160);	//ボックスの幅	// 2009.10.01 ryoji 高DPI対応スケーリング
						Toolbar_SetButtonInfo( m_hwndToolBar, tbb.idCommand, &tbi );

						//位置とサイズを取得する
						rc.right = rc.left = rc.top = rc.bottom = 0;
						Toolbar_GetItemRect( m_hwndToolBar, count-1, &rc );

						//コンボボックスを作る
						//	Mar. 8, 2003 genta 検索ボックスを1ドット下にずらした
						m_hwndSearchBox = CreateWindow( _T("COMBOBOX"), _T("Combo"),
								WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWN
								/*| CBS_SORT*/ | CBS_AUTOHSCROLL /*| CBS_DISABLENOSCROLL*/,
								rc.left, rc.top + 1, rc.right - rc.left, (rc.bottom - rc.top) * 10,
								m_hwndToolBar, (HMENU)(INT_PTR)tbb.idCommand, CEditApp::getInstance()->GetAppInstance(), NULL );
						if( m_hwndSearchBox )
						{
							m_pOwner->SetCurrentFocus(0);

							lf = m_pOwner->GetLogfont();
							//memset_raw( &lf, 0, sizeof(lf) );
							lf.lfHeight			= DpiPointsToPixels(-9); // Jan. 14, 2003 genta ダイアログにあわせてちょっと小さく	// 2009.10.01 ryoji 高DPI対応(ポイント数から算出)
							lf.lfWidth			= 0;
							lf.lfEscapement		= 0;
							lf.lfOrientation	= 0;
							lf.lfWeight			= FW_NORMAL;
							lf.lfItalic			= FALSE;
							lf.lfUnderline		= FALSE;
							lf.lfStrikeOut		= FALSE;
							//lf.lfCharSet		= GetDllShareData().m_Common.m_sView.m_lf.lfCharSet;
							lf.lfOutPrecision	= OUT_TT_ONLY_PRECIS;		// Raster Font を使わないように
							//lf.lfClipPrecision	= GetDllShareData().m_Common.m_sView.m_lf.lfClipPrecision;
							//lf.lfQuality		= GetDllShareData().m_Common.m_sView.m_lf.lfQuality;
							//lf.lfPitchAndFamily	= GetDllShareData().m_Common.m_sView.m_lf.lfPitchAndFamily;
							//_tcsncpy( lf.lfFaceName, GetDllShareData().m_Common.m_sView.m_lf.lfFaceName, _countof(lf.lfFaceName));	// 画面のフォントに設定	2012/11/27 Uchi
							m_hFontSearchBox = ::CreateFontIndirect( &lf );
							if( m_hFontSearchBox )
							{
								::SendMessage( m_hwndSearchBox, WM_SETFONT, (WPARAM)m_hFontSearchBox, MAKELONG (TRUE, 0) );
							}

							// //入力長制限
							// Combo_LimitText( m_hwndSearchBox, (WPARAM)_MAX_PATH - 1 );

							//検索ボックスを更新	// 関数化 2010/6/6 Uchi
							AcceptSharedSearchKey();

							m_comboDel = SComboBoxItemDeleter(); // 再表示用の初期化
							m_comboDel.pRecent = &m_cRecentSearch;
							CDialog::SetComboBoxDeleter(m_hwndSearchBox, &m_comboDel);
						}
						break;

					default:
						break;
					}
				}
				break;

			case TBSTYLE_BUTTON:	//ボタン
			case TBSTYLE_SEP:		//セパレータ
			default:
				Toolbar_AddButtons( m_hwndToolBar, 1, &tbb );
				count++;
				break;
			}
			//@@@ 2002.06.15 MIK end
		}
		if( GetDllShareData().m_Common.m_sToolBar.m_bToolBarIsFlat ){	/* フラットツールバーにする/しない */
			lToolType = ::GetWindowLongPtr(m_hwndToolBar, GWL_STYLE);
			lToolType |= (TBSTYLE_FLAT);
			::SetWindowLongPtr(m_hwndToolBar, GWL_STYLE, lToolType);
			::InvalidateRect(m_hwndToolBar, NULL, TRUE);
		}
		delete []pTbbArr;// 2005/8/29 aroka
	}

	// 2006.06.17 ryoji
	// ツールバーを Rebar に入れる
	if( m_hwndReBar && m_hwndToolBar ){
		// ツールバーの高さを取得する
		DWORD dwBtnSize = Toolbar_GetButtonSize( m_hwndToolBar );
		DWORD dwRows = Toolbar_GetRows( m_hwndToolBar );

		// バンド情報を設定する
		// 以前のプラットフォームに _WIN32_WINNT >= 0x0600 で定義される構造体のフルサイズを渡すと失敗する	// 2007.12.21 ryoji
		rbBand.cbSize = CCSIZEOF_STRUCT( REBARBANDINFO, wID );
		rbBand.fMask  = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
		rbBand.fStyle = RBBS_CHILDEDGE;
		rbBand.hwndChild  = m_hwndToolBar;	// ツールバー
		rbBand.cxMinChild = 0;
		rbBand.cyMinChild = HIWORD(dwBtnSize) * dwRows;
		rbBand.cx         = 250;

		// バンドを追加する
		Rebar_InsertBand( m_hwndReBar, -1, &rbBand );
		::ShowWindow( m_hwndToolBar, SW_SHOW );
	}

	return;
}
예제 #6
0
파일: shell.cpp 프로젝트: beru/sakura
/*!	独自拡張プロパティシートのウィンドウプロシージャ
	@author ryoji
	@date 2007.05.25 新規
*/
static LRESULT CALLBACK PropSheetWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch( uMsg ){
	case WM_SHOWWINDOW:
		// 追加ボタンの位置を調整する
		if( wParam ){
			HWND hwndBtn;
			RECT rcOk;
			RECT rcTab;
			POINT pt;

			hwndBtn = ::GetDlgItem( hwnd, 0x02000 );
			::GetWindowRect( ::GetDlgItem( hwnd, IDOK ), &rcOk );
			::GetWindowRect( PropSheet_GetTabControl( hwnd ), &rcTab );
			pt.x = rcTab.left;
			pt.y = rcOk.top;
			::ScreenToClient( hwnd, &pt );
			::MoveWindow( hwndBtn, pt.x, pt.y, DpiScaleX(140), rcOk.bottom - rcOk.top, FALSE );
		}
		break;

	case WM_COMMAND:
		// 追加ボタンが押された時はその処理を行う
		if( HIWORD( wParam ) == BN_CLICKED && LOWORD( wParam ) == 0x02000 ){
			HWND hwndBtn = ::GetDlgItem( hwnd, 0x2000 );
			RECT rc;
			POINT pt;

			// メニューを表示する
			::GetWindowRect( hwndBtn, &rc );
			pt.x = rc.left;
			pt.y = rc.bottom;
			GetMonitorWorkRect( pt, &rc );	// モニタのワークエリア

			HMENU hMenu = ::CreatePopupMenu();
			::InsertMenu( hMenu, 0, MF_BYPOSITION | MF_STRING, 100, LS(STR_SHELL_MENU_OPEN) );
			::InsertMenu( hMenu, 1, MF_BYPOSITION | MF_STRING, 101, LS(STR_SHELL_MENU_IMPEXP) );

			int nId = ::TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD,
										( pt.x > rc.left )? pt.x: rc.left,
										( pt.y < rc.bottom )? pt.y: rc.bottom,
										0, hwnd, NULL );
			::DestroyMenu( hMenu );

			// 選択されたメニューの処理
			switch( nId ){
			case 100:	// 設定フォルダを開く
				TCHAR szPath[_MAX_PATH];
				GetInidir( szPath );

				// フォルダの ITEMIDLIST を取得して ShellExecuteEx() で開く
				// Note. MSDN の ShellExecute() の解説にある方法でフォルダを開こうとした場合、
				//       フォルダと同じ場所に <フォルダ名>.exe があるとうまく動かない。
				//       verbが"open"やNULLではexeのほうが実行され"explore"では失敗する
				//       (フォルダ名の末尾に'\\'を付加してもWindows 2000では付加しないのと同じ動作になってしまう)
				LPSHELLFOLDER pDesktopFolder;
				if( SUCCEEDED(::SHGetDesktopFolder(&pDesktopFolder)) ){
					LPMALLOC pMalloc;
					if( SUCCEEDED(::SHGetMalloc(&pMalloc)) ){
						LPITEMIDLIST pIDL;
						WCHAR pwszDisplayName[_MAX_PATH];
						_tcstowcs(pwszDisplayName, szPath, _countof(pwszDisplayName));
//#ifdef _UNICODE
//						pwszDisplayName = szPath;
//#else
//						WCHAR wszPath[_MAX_PATH];
//						::MultiByteToWideChar( CP_ACP, 0, szPath, -1, wszPath, _MAX_PATH );
//						pwszDisplayName = wszPath;
//#endif
						if( SUCCEEDED(pDesktopFolder->ParseDisplayName(NULL, NULL, pwszDisplayName, NULL, &pIDL, NULL)) ){
							SHELLEXECUTEINFO si;
							::ZeroMemory( &si, sizeof(si) );
							si.cbSize   = sizeof(si);
							si.fMask    = SEE_MASK_IDLIST;
							si.lpVerb   = _T("open");
							si.lpIDList = pIDL;
							si.nShow    = SW_SHOWNORMAL;
							::ShellExecuteEx( &si );	// フォルダを開く
							pMalloc->Free( (void*)pIDL );
						}
						pMalloc->Release();
					}
					pDesktopFolder->Release();
				}
				break;
			case 101:	// インポート/エクスポートの起点リセット(起点を設定フォルダにする)
				int nMsgResult = MYMESSAGEBOX(
					hwnd,
					MB_OKCANCEL | MB_ICONINFORMATION,
					GSTR_APPNAME,
					LS(STR_SHELL_IMPEXPDIR)
				);
				if( IDOK == nMsgResult )
				{
					DLLSHAREDATA *pShareData = &GetDllShareData();
					GetInidir( pShareData->m_sHistory.m_szIMPORTFOLDER );
					AddLastChar( pShareData->m_sHistory.m_szIMPORTFOLDER, _countof2(pShareData->m_sHistory.m_szIMPORTFOLDER), _T('\\') );
				}
				break;
			}
		}
		break;

	case WM_DESTROY:
		::SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)s_pOldPropSheetWndProc );
		break;
	}

	return ::CallWindowProc( s_pOldPropSheetWndProc, hwnd, uMsg, wParam, lParam );
}
예제 #7
0
static inline SizeI GetTabSize(HWND hwnd)
{
    int dx = DpiScaleX(hwnd, std::max(gGlobalPrefs->prereleaseSettings.tabWidth, MIN_TAB_WIDTH));
    int dy = DpiScaleY(hwnd, TABBAR_HEIGHT);
    return SizeI(dx, dy);
}
예제 #8
0
    // Paints the tabs that intersect the window's update rectangle.
    void Paint(HDC hdc, RECT &rc) {
        IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);

        // paint the background
        bool isTranslucentMode = inTitlebar && dwm::IsCompositionEnabled();
        if (isTranslucentMode)
            PaintParentBackground(hwnd, hdc);
        else {
            HBRUSH brush = CreateSolidBrush(color.bar);
            FillRect(hdc, &rc, brush);
            DeleteObject(brush);
        }

        // TODO: GDI+ doesn't seem to cope well with SetWorldTransform
        XFORM ctm = { 1.0, 0, 0, 1.0, 0, 0 };
        SetWorldTransform(hdc, &ctm);

        Graphics graphics(hdc);
        graphics.SetCompositingMode(CompositingModeSourceCopy);
        graphics.SetCompositingQuality(CompositingQualityHighQuality);
        graphics.SetSmoothingMode(SmoothingModeHighQuality);
        graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
        graphics.SetPageUnit(UnitPixel);
        GraphicsPath shapes(data->Points, data->Types, data->Count);
        GraphicsPath shape;
        GraphicsPathIterator iterator(&shapes);

        SolidBrush br(Color(0, 0, 0));
        Pen pen(&br, 2.0f);

        Font f(hdc, GetDefaultGuiFont());
        // TODO: adjust these constant values for DPI?
        RectF layout((REAL)DpiScaleX(hwnd,3), 1.0f, REAL(width - DpiScaleX(hwnd,20)), (REAL)height);
        StringFormat sf(StringFormat::GenericDefault());
        sf.SetFormatFlags(StringFormatFlagsNoWrap);
        sf.SetLineAlignment(StringAlignmentCenter);
        sf.SetTrimming(StringTrimmingEllipsisCharacter);

        REAL yPosTab = inTitlebar ? 0.0f : REAL(ClientRect(hwnd).dy - height - 1);
        for (int i = 0; i < Count(); i++) {
            graphics.ResetTransform();
            graphics.TranslateTransform(1.f + (REAL)(width + 1) * i - (REAL)rc.left, yPosTab - (REAL)rc.top);

            if (!graphics.IsVisible(0, 0, width + 1, height + 1))
                continue;

            // in firefox style we only paint current and highlighed tabs
            // all other tabs only show
            bool onlyText = g_FirefoxStyle && !((current == i) || (highlighted == i));
            if (onlyText) {
#if 0
                // we need to first paint the background with the same color as caption,
                // otherwise the text looks funny (because is transparent?)
                // TODO: what is the damn bg color of caption? bar is too light, outline is too dark
                Color bgColTmp;
                bgColTmp.SetFromCOLORREF(color.bar);
                {
                    SolidBrush bgBr(bgColTmp);
                    graphics.FillRectangle(&bgBr, layout);
                }
                bgColTmp.SetFromCOLORREF(color.outline);
                {
                    SolidBrush bgBr(bgColTmp);
                    graphics.FillRectangle(&bgBr, layout);
                }
#endif
                // TODO: this is a hack. If I use no background and cleartype, the
                // text looks funny (is bold).
                // CompositingModeSourceCopy doesn't work with clear type
                // another option is to draw background before drawing text, but
                // I can't figure out what is the actual color of caption
                graphics.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
                graphics.SetCompositingMode(CompositingModeSourceCopy);
                //graphics.SetCompositingMode(CompositingModeSourceOver);
                br.SetColor(ToColor(color.text));
                graphics.DrawString(text.At(i), -1, &f, layout, &sf, &br);
                graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
                continue;
            }

            COLORREF bgCol = color.background;;
            if (current == i) {
                bgCol = color.current;
            } else if (highlighted == i) {
                bgCol = color.highlight;
            }

            // ensure contrast between text and background color
            // TODO: adjust threshold (and try adjusting both current/background tabs)
            COLORREF textCol = color.text;
            float bgLight = GetLightness(bgCol), textLight = GetLightness(textCol);
            if (textLight < bgLight ? bgLight < 0x70 : bgLight > 0x90)
                textCol = textLight ? AdjustLightness(textCol, 255.0f / textLight - 1.0f) : RGB(255, 255, 255);
            if (fabs(textLight - bgLight) < 0x40)
                textCol = bgLight < 0x80 ? RGB(255, 255, 255) : RGB(0, 0, 0);

            // paint tab's body
            graphics.SetCompositingMode(CompositingModeSourceCopy);
            iterator.NextMarker(&shape);
            br.SetColor(ToColor(bgCol));
            graphics.FillPath(&br, &shape);

            // draw tab's text
            graphics.SetCompositingMode(CompositingModeSourceOver);
            br.SetColor(ToColor(textCol));
            graphics.DrawString(text.At(i), -1, &f, layout, &sf, &br);

            // paint "x"'s circle
            iterator.NextMarker(&shape);
            if (xClicked == i || xHighlighted == i) {
                br.SetColor(ToColor(i == xClicked ? color.x_click : color.x_highlight));
                graphics.FillPath(&br, &shape);
            }

            // paint "x"
            iterator.NextMarker(&shape);
            if (xClicked == i || xHighlighted == i)
                pen.SetColor(ToColor(color.x_line));
            else
                pen.SetColor(ToColor(color.outline));
            graphics.DrawPath(&pen, &shape);
            iterator.Rewind();
        }
    }
예제 #9
0
    // Paints the tabs that intersect the window's update rectangle.
    void Paint(HDC hdc, RECT& rc) {
        IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);

// paint the background
#if 0
        bool isTranslucentMode = inTitlebar && dwm::IsCompositionEnabled();
        if (isTranslucentMode) {
            PaintParentBackground(hwnd, hdc);
        } else {
            // note: not sure what color should be used here and painting
            // background works fine
            /*HBRUSH brush = CreateSolidBrush(colors.bar);
            FillRect(hdc, &rc, brush);
            DeleteObject(brush);*/
        }
#else
        PaintParentBackground(hwnd, hdc);
#endif
        // TODO: GDI+ doesn't seem to cope well with SetWorldTransform
        XFORM ctm = {1.0, 0, 0, 1.0, 0, 0};
        SetWorldTransform(hdc, &ctm);

        Graphics gfx(hdc);
        gfx.SetCompositingMode(CompositingModeSourceCopy);
        gfx.SetCompositingQuality(CompositingQualityHighQuality);
        gfx.SetSmoothingMode(SmoothingModeHighQuality);
        gfx.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
        gfx.SetPageUnit(UnitPixel);
        GraphicsPath shapes(data->Points, data->Types, data->Count);
        GraphicsPath shape;
        GraphicsPathIterator iterator(&shapes);

        SolidBrush br(Color(0, 0, 0));
        Pen pen(&br, 2.0f);

        Font f(hdc, GetDefaultGuiFont());
        // TODO: adjust these constant values for DPI?
        RectF layout((REAL)DpiScaleX(hwnd, 3), 1.0f, REAL(width - DpiScaleX(hwnd, 20)), (REAL)height);
        StringFormat sf(StringFormat::GenericDefault());
        sf.SetFormatFlags(StringFormatFlagsNoWrap);
        sf.SetLineAlignment(StringAlignmentCenter);
        sf.SetTrimming(StringTrimmingEllipsisCharacter);

        REAL yPosTab = inTitlebar ? 0.0f : REAL(ClientRect(hwnd).dy - height - 1);
        for (int i = 0; i < Count(); i++) {
            gfx.ResetTransform();
            gfx.TranslateTransform(1.f + (REAL)(width + 1) * i - (REAL)rc.left, yPosTab - (REAL)rc.top);

            if (!gfx.IsVisible(0, 0, width + 1, height + 1))
                continue;

            // Get the correct colors based on the state and the current theme
            COLORREF bgCol = GetAppColor(AppColor::TabBackgroundBg);
            COLORREF textCol = GetAppColor(AppColor::TabBackgroundText);
            COLORREF xColor = GetAppColor(AppColor::TabBackgroundCloseX);
            COLORREF circleColor = GetAppColor(AppColor::TabBackgroundCloseCircle);

            if (selectedTabIdx == i) {
                bgCol = GetAppColor(AppColor::TabSelectedBg);
                textCol = GetAppColor(AppColor::TabSelectedText);
                xColor = GetAppColor(AppColor::TabSelectedCloseX);
                circleColor = GetAppColor(AppColor::TabSelectedCloseCircle);
            } else if (highlighted == i) {
                bgCol = GetAppColor(AppColor::TabHighlightedBg);
                textCol = GetAppColor(AppColor::TabHighlightedText);
                xColor = GetAppColor(AppColor::TabHighlightedCloseX);
                circleColor = GetAppColor(AppColor::TabHighlightedCloseCircle);
            }
            if (xHighlighted == i) {
                xColor = GetAppColor(AppColor::TabHoveredCloseX);
                circleColor = GetAppColor(AppColor::TabHoveredCloseCircle);
            }
            if (xClicked == i) {
                xColor = GetAppColor(AppColor::TabClickedCloseX);
                circleColor = GetAppColor(AppColor::TabClickedCloseCircle);
            }

            // paint tab's body
            gfx.SetCompositingMode(CompositingModeSourceCopy);
            iterator.NextMarker(&shape);
            br.SetColor(ToColor(bgCol));
            Point points[4];
            shape.GetPathPoints(points, 4);
            Rect body(points[0].X, points[0].Y, points[2].X - points[0].X, points[2].Y - points[0].Y);
            body.Inflate(0, 0);
            gfx.SetClip(body);
            body.Inflate(5, 5);
            gfx.FillRectangle(&br, body);
            gfx.ResetClip();

            // draw tab's text
            gfx.SetCompositingMode(CompositingModeSourceOver);
            br.SetColor(ToColor(textCol));
            gfx.DrawString(text.at(i), -1, &f, layout, &sf, &br);

            // paint "x"'s circle
            iterator.NextMarker(&shape);
            bool closeCircleEnabled = true;
            if ((xClicked == i || xHighlighted == i) && closeCircleEnabled) {
                br.SetColor(ToColor(circleColor));
                gfx.FillPath(&br, &shape);
            }

            // paint "x"
            iterator.NextMarker(&shape);
            pen.SetColor(ToColor(xColor));
            gfx.DrawPath(&pen, &shape);
            iterator.Rewind();
        }
    }
예제 #10
0
/* ツールバーボタンリストのアイテム描画
	@date 2003.08.27 Moca システムカラーのブラシはCreateSolidBrushをやめGetSysColorBrushに
	@date 2005.08.09 aroka CPropCommon.cpp から移動
	@date 2007.11.02 ryoji ボタンとセパレータとで処理を分ける
*/
void CPropToolbar::DrawToolBarItemList( DRAWITEMSTRUCT* pDis )
{
	TBBUTTON	tbb;
	HBRUSH		hBrush;
	RECT		rc;
	RECT		rc0;
	RECT		rc1;
	RECT		rc2;


//	hBrush = ::CreateSolidBrush( ::GetSysColor( COLOR_WINDOW ) );
	hBrush = ::GetSysColorBrush( COLOR_WINDOW );
	::FillRect( pDis->hDC, &pDis->rcItem, hBrush );
//	::DeleteObject( hBrush );

	rc  = pDis->rcItem;
	rc0 = pDis->rcItem;
	rc0.left += GetSystemMetrics(SM_CXSMICON) + DpiScaleX(2);
	rc1 = rc0;
	rc2 = rc0;

	if( (int)pDis->itemID < 0 ){
	}else{

//@@@ 2002.01.03 YAZAKI m_tbMyButtonなどをCShareDataからCMenuDrawerへ移動したことによる修正。
//		tbb = m_cShareData.m_tbMyButton[pDis->itemData];
//		tbb = m_pcMenuDrawer->m_tbMyButton[pDis->itemData];
		tbb = m_pcMenuDrawer->getButton(pDis->itemData);

		// ボタンとセパレータとで処理を分ける	2007.11.02 ryoji
		WCHAR	szLabel[256];
		if( tbb.fsStyle & TBSTYLE_SEP ){
			// テキストだけ表示する
			if( tbb.idCommand == F_SEPARATOR ){
				auto_strncpy( szLabel, LSW(STR_PROPCOMTOOL_ITEM1), _countof(szLabel) - 1 );	// nLength 未使用 2003/01/09 Moca
				szLabel[_countof(szLabel) - 1] = L'\0';
			}else if( tbb.idCommand == F_MENU_NOT_USED_FIRST ){
				// ツールバー折返
				auto_strncpy( szLabel, LSW(STR_PROPCOMTOOL_ITEM2), _countof(szLabel) - 1 );
				szLabel[_countof(szLabel) - 1] = L'\0';
			}else{
				auto_strncpy( szLabel, LSW(STR_PROPCOMTOOL_ITEM3), _countof(szLabel) - 1 );
				szLabel[_countof(szLabel) - 1] = L'\0';
			}
		//	From Here Oct. 15, 2001 genta
		}else{
			// アイコンとテキストを表示する
			m_pcIcons->Draw( tbb.iBitmap, pDis->hDC, rc.left + 2, rc.top + 2, ILD_NORMAL );
			m_cLookup.Funccode2Name( tbb.idCommand, szLabel, _countof( szLabel ) );
		}
		//	To Here Oct. 15, 2001 genta

		/* アイテムが選択されている */
		if( pDis->itemState & ODS_SELECTED ){
//			hBrush = ::CreateSolidBrush( ::GetSysColor( COLOR_HIGHLIGHT ) );
			hBrush = ::GetSysColorBrush( COLOR_HIGHLIGHT );
			::SetTextColor( pDis->hDC, ::GetSysColor( COLOR_HIGHLIGHTTEXT ) );
		}else{
//			hBrush = ::CreateSolidBrush( ::GetSysColor( COLOR_WINDOW ) );
			hBrush = ::GetSysColorBrush( COLOR_WINDOW );
			::SetTextColor( pDis->hDC, ::GetSysColor( COLOR_WINDOWTEXT ) );
		}
		rc1.left++;
		rc1.top++;
		rc1.right--;
		rc1.bottom--;
		::FillRect( pDis->hDC, &rc1, hBrush );
//		::DeleteObject( hBrush );

		::SetBkMode( pDis->hDC, TRANSPARENT );
		// 2014.11.25 topマージンが2固定だとフォントが大きい時に見切れるので変数に変更
		TextOutW_AnyBuild( pDis->hDC, rc1.left + 4, rc1.top + nToolBarListBoxTopMargin, szLabel, wcslen( szLabel ) );

	}

	/* アイテムにフォーカスがある */
	if( pDis->itemState & ODS_FOCUS ){
		::DrawFocusRect( pDis->hDC, &rc2 );
	}
	return;
}