天天看點

關于無邊框視窗的相容性問題

昨天在虛拟機(XP SP3)測試程式的時候,發現無邊框視窗均無法正常顯示視窗,之後我又去Win7下測試,發現在開啟Areo的情況下,不管是不是開啟了透明,視窗都可以正常顯示(和Win8一樣),如果沒有開啟Areo,即選擇“Win7 Basic”主題,無邊框視窗和在Xp下一樣,無法顯示,于是經過查資料研究,終于找到了一個解決方法。

這是原來的視窗無邊框的方法,核心是SetWindowLong修改了視窗風格。

//這裡是在建構視窗類結構
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;//視窗回調函數指針
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;//執行個體句柄
	wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);//預設指針
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = AppName;//視窗類名

	//注冊視窗類
	if (!RegisterClass(&wc))
	{
		MessageBox(NULL, TEXT("注冊視窗類失敗!"), TEXT("錯誤"), MB_ICONERROR);
		return 0;
	}

	//建立視窗
	int style = WS_OVERLAPPEDWINDOW;
	hwnd1 = CreateWindowEx(NULL, AppName, TEXT("視窗标題"), style, 50, 50, 500, 500, 0, LoadMenu(hInstance, TEXT("MENU1")), hInstance, 0);
	if (hwnd1 == NULL)
	{
		MessageBox(NULL, TEXT("建立視窗失敗!"), TEXT("錯誤"), MB_ICONERROR);
		return 0;
	}
	//無邊框視窗
	SetWindowLong(hwnd1, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

	//顯示、更新視窗
	ShowWindow(hwnd1, nCmdShow);
	UpdateWindow(hwnd1);

	//消息循環。。。。。。
           

在XP和Win7非Areo環境下,需要這樣修改,同時,修改後的代碼在Win7Areo和Win8下也能正常顯示

1。将CreateWindow、CreateWindowEx的視窗坐标,視窗寬度高度統統改為0。

hwnd1 = CreateWindowEx(NULL, AppName, TEXT("視窗标題"), style, 0, 0, 0, 0, 0, LoadMenu(hInstance, TEXT("MENU1")), hInstance, 0);
           

2。添加如下代碼,在SetWindowLong之後或UpdateWindow之後均可

SetWindowPos(hwnd1, HWND_TOP, 視窗x坐标, 視窗y坐标, 寬度, 高度, SWP_SHOWWINDOW);
           

修改之後的代碼如下:

//這裡是在建構視窗類結構
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;//視窗回調函數指針
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;//執行個體句柄
	wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);//預設指針
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = AppName;//視窗類名

	//注冊視窗類
	if (!RegisterClass(&wc))
	{
		MessageBox(NULL, TEXT("注冊視窗類失敗!"), TEXT("錯誤"), MB_ICONERROR);
		return 0;
	}

	//建立視窗
	int style = WS_OVERLAPPEDWINDOW;
	hwnd1 = CreateWindowEx(NULL, AppName, TEXT("視窗标題"), style, 0, 0, 0, 0, 0, LoadMenu(hInstance, TEXT("MENU1")), hInstance, 0);
	if (hwnd1 == NULL)
	{
		MessageBox(NULL, TEXT("建立視窗失敗!"), TEXT("錯誤"), MB_ICONERROR);
		return 0;
	}
	//無邊框視窗
	SetWindowLong(hwnd1, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
	SetWindowPos(hwnd1, HWND_TOP, 50, 50, 500, 500, SWP_SHOWWINDOW);

	//顯示、更新視窗
	ShowWindow(hwnd1, nCmdShow);
	UpdateWindow(hwnd1);

	//消息循環
           

改完之後,相容性問題就解決了。

但其實,最正規最友善最可靠的方法就是:

視窗風格隻用WS_POPUP即可,上面都是一些旁門左道!

就像這樣就行了,也沒有相容性問題:

hwnd1 = CreateWindowEx(NULL, AppName, TEXT("視窗标題"), WS_POPUP, 50, 50, 500, 500, 0, LoadMenu(hInstance, TEXT("MENU1")), hInstance, 0);

【聲明】我以前的博文中無邊框這一塊均沒有注意到這個問題,也就是說那些博文中的代碼均有對低版本系統的相容性問題,但因時間有限不作修改,受影響的博文有:

[Win32SDK基本]視窗詳解(超詳細)(中關于無邊框的)

GdiplusFlat(10)自繪Edit Control邊框的實作(附Edit Control垂直居中問題)

GdiplusFlat(9)自繪按鈕的實作(方法2)

GdiplusFlat(8)自繪按鈕的實作(方法1)

GdiplusFlat(7)雙緩沖繪圖和DC透明複制

GdiplusFlat(6)繪制文本

GdiplusFlat(5)畫圖檔

GdiplusFlat(4)單色畫刷和線性漸變畫刷

GdiplusFlat(3)GdipCreateFromHDC函數和畫筆(Pen)



繼續閱讀