2010-12-13 27 views
5

Tôi đang làm việc trên ứng dụng Win32 GUI sử dụng API Win32 thuần túy (không có MFC hoặc .NET). Vấn đề tôi gặp phải là việc kiểm soát xuất hiện trong suốt. Tôi đã tìm ra một phương pháp mà làm việc cho hầu hết mọi thứ, trong Windows Vista + I làm điều này trong WndProc:Điều khiển trong suốt Win32 trên tất cả các phiên bản củaWindows

case WM_CTLCOLORSTATIC: 
{ 
    SetBkMode((HDC)wParam, TRANSPARENT); 
    return (INT_PTR)::GetStockObject(NULL_PEN); 
} 
break; 

Trong Windows XP, tôi làm điều này trong WndProc:

case WM_CTLCOLORSTATIC: 
{ 
    HBRUSH hbr = (HBRUSH)DefWindowProc(hDlg, message, wParam, lParam); 
    ::DeleteObject(hbr); 
    SetBkMode((HDC)wParam, TRANSPARENT); 
    return (LRESULT)(HBRUSH)(COLOR_WINDOW); 
} 

Bây giờ Điều này làm việc cho hầu hết các điều khiển, tuy nhiên tôi nhận được một nền trong suốt trên nhãn trên đầu trang của một điều khiển hộp nhóm mà rút ra các dòng hộp nhóm thông qua văn bản. Tôi bắt đầu làm việc hướng tới một trường hợp chỉ cho các hộp nhóm nhưng tôi chắc chắn rằng đây là một vấn đề phải được giải quyết trước đây và tôi không muốn phát minh lại bánh xe.

Có phương pháp thử và kiểm tra để kiểm soát xuất hiện trong suốt không?

Cảm ơn, J

+1

Tôi không nghĩ bạn nên xóa bàn chải như vậy ... – Anders

+0

Bạn có chắc chắn rằng kênh alpha có sẵn trên tất cả các nền tảng bạn muốn không? Còn những người phải sử dụng ứng dụng của bạn trên PC chạy Terminal Services, Remote Desktop hoặc Windows Server thì sao?Bạn có ý gì bởi "Tất cả các phiên bản của cửa sổ"? Windows 98? Đó cũng là Win32! Có thể bạn có thể nói "Tất cả các phiên bản Windows từ Windows XP và mới hơn" nếu đó là ý của bạn. –

+0

Bạn có lẽ đúng về điều đó, nó hoạt động cho dù tôi xóa bàn chải hay không. Tôi không nhớ mình đã lấy mã đó từ đâu nhưng có một lời giải thích là tại sao bàn chải lại bị xóa như thế. – JWood

Trả lời

6

Để đạt được điều khiển trong suốt bạn sẽ cần phải nhận thức được rằng:

  • Bạn có thể không thực sự. Các điều khiển cửa sổ tiêu chuẩn chỉ không hỗ trợ bức tranh "trong suốt".
  • Ngay cả khi bạn làm đúng, hộp thoại sẽ nhấp nháy nếu bạn đổi kích thước.
  • 'Hacks' để có được bức tranh minh bạch về các điều khiển hoạt động có xu hướng khác nhau nếu chúng đang bật hoặc tắt, và thay đổi giữa các phiên bản cửa sổ.

Thông thường mục tiêu của việc kiểm soát "trong suốt" là sao cho da bitmap trong các điều khiển hiển thị qua. Cách để đạt được loại minh bạch này là tạo một bitmap cho nền của điều khiển. Sau đó, sử dụng CreatePatternBrush từ bitmap.

đoạn mã này DialogProc thực hiện các phương pháp lột da đơn giản nhất có thể và sau đó sẽ chăm sóc vẽ cả nền của hộp thoại, và hầu hết các điều khiển hỗ trợ hình thức này của bức tranh:

// _hwnd is the dialogs handle 
    // _hbrSkin is a pattern brush handle 
    HWND hwndCtl; 
    POINT pt; 
    HDC hdc; 
case WM_CTLCOLORDLG: 
    return (INT_PTR)_hbrSkin; 
case WM_CTLCOLORSTATIC: 
case WM_CTLCOLORBTN: 
    hdc = (HDC)wParam; 
    SetBkMode(hdc,TRANSPARENT); // Ensure that "static" text doesn't use a solid fill 
    pt.x = 0; pt.y = 0; 
    MapWindowPoints(hwndCtl,_hwnd,&pt,1); 
    SetBrushOrgEx(hdc,-pt.x,-pt.y,NULL); 
    return (INT_PTR)_hbrSkin; 

Controls mà chồng lên nhau sẽ vẽ không chính xác như một sẽ sơn nền "trong suốt" của nó trên khác. Bạn có thể giảm nhấp nháy theo:

  • Không cho phép thay đổi kích cỡ hộp thoại.
  • đặt kiểu WS_EX_COMPOSITED trên hộp thoại, nhưng vì DWM Windows NT 6 không hỗ trợ nó, về cơ bản nó vô dụng từ Vista.
  • Đặt kiểu WS_CLIPCHILDREN trên hộp thoại & hoặc WS_CLIPSIBLINGS - những kiểu này ngăn việc sử dụng các hộp nhóm và điều khiển tab khi chúng dựa vào các điều khiển chồng chéo.
  • phân lớp tất cả các điều khiển, sử dụng thông báo WM_PRINTCLIENT để vẽ chúng vào bộ đệm sau, sau đó đánh dấu bộ đệm sau đã chuẩn bị trong một lần truyền. Công việc khó khăn và không phải tất cả các điều khiển đều hỗ trợ WM_PRINTCLIENT.
+0

+1, tóm tắt tuyệt vời và bao gồm các cuộc gọi SetBrushOrgEx dễ dàng bỏ qua nếu thử nghiệm với một nền tảng vững chắc. –

Các vấn đề liên quan