2010-01-18 5 views
3

Vista/Win7 그라데이션 반올림이 필요한 툴바와 유사한 코드를 업데이트하고 싶습니다.단추, 도구 모음, 탭 등의 그라디언트 수동 그리기?

현재 버튼에는 Windows 2000 모양이 있습니다. & 느낌 : 블록 형, 단일 톤.

XP 테마로 놀았으며 DrawThemeBackground, DrawThemeEdge 등을 사용했습니다. 하지만 테마 그리기 기법에 매우 만족하지 않습니다 (버튼은 큽니다. 테마는 버튼이 작을 때 괜찮아 보이는 2 톤, 위아래 및 아래쪽 절반으로 그립니다). 그래디언트이거나 둥근 정도의 품질을 지니고 있습니다. 그러나이 버튼만큼 큰 것은 어리석은 것처럼 보입니다.

몇 가지 컨트롤이 여러 앱과 컨트롤에서 그려지는 것을 실험 해 봄으로써 그것들은 그라디언트를 사용하는 것처럼 보입니다 - 컨트롤의 상단이 밝은 색으로 보이고 아래쪽이 어두운 색으로 희미 해집니다 - 또는 - 위쪽의 배경보다 밝은 색이 중간에 가까운 흰색쪽으로 증가하고, 아래쪽으로 갈수록 어두워집니다.

저는 여기에서 어디로 가야할지 모르겠다. DrawThemeXXX는 부적절한 것 같습니다. 전체 컨트롤을 드로잉을 개선 한 새 컨트롤로 바꾸고 싶지는 않지만 현재 사용자 지정 컨트롤의 작동 방식에 대한 일부 코드를 바꿔야하고 다른 라이브러리의 다양한 문제가 발생할 수 있습니다. 필자는 현재 실행중인 Windows의 현재 버전 스타일로 임의의 개체를 그릴 수있는 방법을 찾고 싶습니다. 나는 테마 드로잉 기능이 이것을 다룰 것이라고 생각했을 것이다. 그러나 그들은 내가 설명한 것처럼 상당히 뇌 손상을 입었다.

누가 나를 가리킬 수 있습니까 'XP, Vista 및 Windows 7에서 현대적인 C++ 응용 프로그램이 사용자 정의 GUI 요소를 그려 세련된 모양을 유지할 수 있다고 생각합니까?'

우리는 현재 MFC, Gdiplus 및 원시 Win32 API를 코드에서 사용합니다.

C++에서 Windows 기반의 최신 GUI 그리기에 대해 많은 것을 알고 있기를 바랍니다.

단지 텍스트 벽이 아니기 때문에 페인트 핸들러의 최신 버전 인 '핫 트래킹'과 에칭 된 테두리와 아이콘 + 텍스트 "

void CPlacesButton::PaintButton(CDC & dc, CRect & rcClient) 
{ 
const int kLabelHeight = 8; 

COLORREF clrHiLt = GetSysColor(COLOR_BTNHIGHLIGHT); 
COLORREF clrShdo = GetSysColor(COLOR_BTNSHADOW); 
COLORREF clrText = GetSysColor(COLOR_BTNTEXT); 
COLORREF clrFace = GetSysColor(COLOR_BTNFACE); 

// draw the button's background & border 

if (m_bPressed || m_bDrawPressed || m_bMouseOnButton) 
{ 
    COLORREF clrDarkened = Darken(clrFace, -0.01f); 
    dc.FillRect(rcClient, &CBrush(clrDarkened)); 

    //dc.Draw3dRect(rcClient, clrShdo, clrHiLt); 
    //dc.RoundRect(&rcClient, CPoint(10,10)); 
    dc.DrawEdge(&rcClient, EDGE_ETCHED, BF_RECT|BF_FLAT); 
    //dc.DrawFrameControl(&rcClient, DFC_BUTTON, DFCS_BUTTONPUSH|DFCS_PUSHED); 
} 
// else if (m_bMouseOnButton) // hot draw 
// //dc.Draw3dRect(rcClient, clrShdo, clrHiLt); 
// dc.DrawEdge(&rcClient, EDGE_ETCHED, BF_RECT); 
// //dc.RoundRect(&rcClient, CPoint(10,10)); 
else 
    dc.FillRect(rcClient, &CBrush(clrFace)); 

// use transparent mode for everything that follows 
dc.SetBkMode(TRANSPARENT); 

// center icon 
CPoint ptIcon((rcClient.Width() - m_nIconSize)/2, ((rcClient.Height() - m_nIconSize)/2) - kLabelHeight); 
if (m_bPressed || m_bDrawPressed) 
    ptIcon.Offset(1, 1); 

// determine the state to draw ourselves in 
const UINT nState = DST_ICON | (IsEnabled() ? DSS_NORMAL : DSS_DISABLED); 

// draw our icon 
dc.DrawState(ptIcon, CSize(m_nIconSize, m_nIconSize), m_hIcon, nState, (HBRUSH)NULL); 

// create & select the font to use for the button's label 
CFont guiFont; 
VERIFY(guiFont.CreateStockObject(DEFAULT_GUI_FONT)); 
AutoSelectGDIObject select_font(dc, guiFont); 

// determine clipping rect for label 
CRect rcText(0, ptIcon.y+m_nIconSize+kLabelHeight, rcClient.Width(), ptIcon.y+m_nIconSize+kLabelHeight); 
rcText.InflateRect(0,20); 
if (m_bPressed || m_bDrawPressed) 
    rcText.OffsetRect(1, 1); 

dc.SetTextColor(clrText); 
if (IsEnabled()) 
    dc.DrawText(m_strCaption, rcText, DT_VCENTER|DT_SINGLELINE|DT_CENTER); 
else 
    dc.GrayString(NULL, NULL, (LPARAM)(LPCTSTR)m_strCaption, 0, rcText.TopLeft().x, rcText.TopLeft().y, rcText.Width(), rcText.Height()); 
} 

는 내가 해봤 다른 어떤 가능성으로 몇 가지 힌트를 표시하기 위해 코드에 주석 변화의 ​​일부를 왼쪽 : 때를 누르면 상태에서 (1,1으로 이동) "우울. 그러나 전체 예제가 없기 때문에 단지 힌트 일뿐입니다.

+0

내 관련 질문보기 http://stackoverflow.com/questions/1819282/how-to-draw-windows-7-taskbar-like-shaded-buttons –

답변

1

MFC만으로는 스키닝이 원활하지 않습니다. 다른 GUI (Qt은 사용자 정의 스키닝에 유용합니다)를 사용하는 것 외에도 SkinCrafter과 같은 솔루션을 볼 수 있습니다.

+0

저는 스키닝을 허용하려고하지 않습니다. 전체 앱. 난 단지 우리가 실행중인 윈도우의 버전처럼 보이고 느껴지는 가끔 "버튼과 같은"또는 "메뉴와 같은"컨트롤을 만들고 싶다. (그래서 비스타는 비스타처럼 보일 것이고 Win7은 어떤 테마로 보일 것인가? 사용자가 Win7 등을 위해 선택한 경우). MFC는 "BUTTON"창 클래스 개체를 실제로 생성하여 CButton을 올바르게 만듭니다. 그러나 창문을 그리는 것은 나에게 불투명하다. 이전에는 표준 버튼 컨트롤을 에뮬레이트하기가 쉬웠습니다 ... 저는 단지 하나의 버튼을 에뮬레이트하고 싶습니다 ... – Mordachai

+0

Qt는 굉장합니다! 특히 QStyle과 http://doc.trolltech.com/4.6/stylesheet.html – ephemient

+3

QT는 몇 가지 맞춤 컨트롤에 대한 추가 기능보다 전체 앱용 프레임 워크에 더 가깝습니다. – Mordachai

4

실제로 Windows의 다양한 버전의 모양을 복제하는 것은 엄청나게 어렵습니다. 특히 앱이 둘 이상의 Windows 버전에서 실행될 수있는 경우에는 특히 어렵습니다.

Win2k/Win95 시대에 API를 제공하겠다고 생각했지만 WinXP는 음영 및 오버레이와 함께 등장했으며 이전 API는 완전히 부적절했습니다.

그래서 그들은 API와 그래픽 프리미티브 세트가 모두 함께 섞여있는 API가 아닌 테마 스터디를 생각해 냈습니다. 하지만 그들은 그래픽 기본 세트를 확장하거나 대체 할 수 없으므로 테마가 표준 세트와 거의 일치 할 때만 작동합니다.

따라서 Win9x/Win2k의 경우. 당신은 지금은 윈도우 실제로 GradientDraw를 사용하지 않는 것으로 의심

DrawTheme 
DwmXXX functions 
GradientFill ?? 

WinVista/7

를 들어
DrawTheme 

WINXP

를 들어
DrawFrameControl 
DrawEdge 

를 사용합니다. 윈도우 매니저 코드에 내장되어있는 DX10 쉐이더를 실제로 사용하고 있을지는 모르겠지만 어떻게해야할지 모르겠다. 대신 GradientDraw를 사용하고있다. 이 코드는 컨트롤 위쪽에서 아래쪽으로 선형 페이드를 제공합니다.

INLINE void SetTrivertex(TRIVERTEX & vtx, int x, int y, COLORREF cr) 
{ 
    vtx.x  = x; 
    vtx.y  = y; 
    vtx.Red = (SHORT)(GetRValue(cr) * 256L); 
    vtx.Green = (SHORT)(GetGValue(cr) * 256L); 
    vtx.Blue = (SHORT)(GetBValue(cr) * 256L); 
    vtx.Alpha = (SHORT)(255 * 256L); 
} 

... 

    // fill the interior from the top down with a gradient that starts at crTop 
    // and ends with the crBottom 
    TRIVERTEX vtx[2]; 
    SetTrivertex (vtx[0], prc->left+1, prc->top+1, crTop); 
    SetTrivertex (vtx[1], prc->right-1, prc->bottom-1, crBottom); 

    GRADIENT_RECT gRect = { 0, 1 }; 
    GradientFill(hdc, vtx, 2, &gRect, 1, GRADIENT_FILL_RECT_V); 
+0

감사합니다. 나는 그것을 사용하게 될지도 모른다. 그러나 나는 그것을 알지 못했다. :) – Mordachai

4

MFC 기능 팩을 언급 한 적이 없습니다. 아직 보셨나요? VS2008 SP1에 포함 된 VS2008 용 다운로드 CDrawingManager에는 많은 특수 효과가 있습니다. 응용 프로그램 테마를 크게 지원합니다.

+0

필자는 시간을 좀 가져야하고 실제로 기능 팩을 조사해야합니다. 나는 2008SP1을 가지고있다. 그래서 아마도 나는 그것을 가지고있다. 필자는 기능 팩으로 어디서부터 시작해야할지 모르겠습니다. 우리의 MFC 응용 프로그램은 크기가 커서 기능 팩을 '떨어 뜨리는'것이 쉽지 않은지 알지 못합니다. – Mordachai

관련 문제