日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

改变窗口的外观和大小

發布時間:2023/12/9 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 改变窗口的外观和大小 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

From: http://blog.csdn.net/yoyobaibai/article/details/6044101


改變窗口的外觀和大小需要在窗口創建以前改變。?所以我們可以在CMainFrame的?PreCreateWindow中改變CREATESTRUCT?結構體的值就行了。

?

E.G.

BOOL?CMainFrame::PreCreateWindow(CREATESTRUCT&?cs)

改變窗口的大小?->?cs.cx?=?300;?cs.cy?=?200;

?

改變窗口的顯示位置坐標是 cs.x 和 cs.y

?

這里常用的一個函數是::GetSysMetrics(SM_CXSCREEN);

::GetSysMetrics(SM_CYSCREEN);

用來取得屏幕的大小。

?

要改變窗口標題欄的字符串:

???cs.lpszName?=?"Seven";?會發現標題欄不會改變窗口的標題欄的上的字符串。

改變單文檔應用程序的標題欄的字符串?參考MSDN??window?styles/Frame-window?styles?下面有一個Changing?the?styles?of?a?window?create?by?MFC./?The?SDI?Case

默認的情況是WS_OVERLAPPEDWINDOW?and?FWS_ADDTOTITLE?styles

FWS_ADDTOTITLE?is?add?the?document?title?to?the?window’s?caption.

去掉FWS_ADDTOTITLE?就可以更改窗口標題欄字符串。

?cs.style?&=?~FWS_ADDTOTITLE;

cs.lpszName?=?"Seven";

?

?

如果我們需要改變背景,?畫刷,?光標等等時候。

我們可以在:PreCreateWindow中創建窗口類,?WNDCLASS?wndClass;

把這個類里的值改變成自己想要的內容就可以了。

E.G.

wndClass.cbClsExtra?=?0;

wndClass.cbWndExtra?=?0;

wndClass.hbrBackground?=?(HBRUSH)GetStockObject(DKGRAY_BRUSH);

wndClass.hCursor?=?LoadCursor(NULL,?IDC_WAIT);

wndClass.hIcon?=?LoadIcon(NULL,?IDI_WARNING);

wndClass.hInstance?=?AfxGetInstanceHandle();

獲取應用程序的實例句柄可用AfxGetInstanceHandle函數,?這個函數是一個全局的函數,?前面有一個AFX表示是一個應用程序框架類函數,哪里都可用。

wndClass.lpfnWndProc?=?::DefWindowProc;

我們只是想要改變窗口的圖標,?光標,不想改變條用過程所以用defWindowProc函數來處理。

因為在CWnd中也有一個defWindowProc函數,比全局的函數少一個參數?如果不加::的話調用就要報錯。

wndClass.lpszMenuName?=?NULL;

創建菜單并不是在在設計窗口類的時候創建,?菜單的創建實在CStyleAPP::InitInstance函數中將菜單的標識傳進去。

wndClass.style?=?CS_HREDRAW?|?CS_VREDRAW;

這里的style并不是窗口的類型而是窗口類的類型。

RegisterClass(&wndClass);

注冊窗口類。

cs.lpszClass?=?"GL";

后來把我們剛剛設計好的類賦值個cs.lpszClass。

?

運行程序之后我們會發現只有圖標改變了,?cursor??和brush都沒有改變。這是因為,?我們是在frame中改變的,在frame上邊還覆蓋一個子窗口類。所以我要改變這些需要把在子窗口的View類中PreCreateWindow中把類名復制。

E.g

在CStyleView中?cs.lpszClass?=?"GL";

就可以把我們剛剛的想要的類型來改變view中的窗口類型,?因為“GL”窗口類已經在CMainFrame框架類中已經注冊了,?所以我們可以直接賦值就可以了。

?

在frame中只可以改變ICON?,為了改變圖標我們重寫窗口類我很不劃算,?在MFC中為我們提供了一個函數AfxRegisterWndClass?直接改變icon詳見MSDN

cs.lpszName?=?AfxRegisterWndClass(CS_HREDRAW?|?CS_VREDRAW,?0,?0,

LoadIcon(NULL,?IDI_WARNING));

這樣就直接改變了frame中Icon。?

我們也可以在CStyleView中調用這個函數?來改變窗口的?畫刷,?光標。

?

窗口創建之后改變外觀

用SetWinowLong函數?具體見MSDN

LONG?SetWindowLong( ??HWND?hWnd,??????//?handle?of?window ?

?int?nIndex,?????//?offset?of?value?to?set ??

?LONG?dwNewLong???//?new?value );

在CMainFrame的OnCreate中調用SetWindowLong

????SetWindowLong(m_hWnd,?GWL_STYLE,?WS_OVERLAPPEDWINDOW);

這樣就可以去掉了文檔標題是窗口標題了。

我們可以通過GetWindowLong函數得到當前窗口的類型。?詳見MSDN

???SetWindowLong(m_hWnd,?GWL_STYLE,?GetWindowLong(m_hWnd,?GWL_STYLE)?&?~WS_MAXIMIZEBOX);

這樣就可以灰掉窗口的最大化窗口了。

?

窗口創建之后改變窗口類

上面的是改變窗口的大小和最大化最小化等等的按鈕。

我們可以用SetClassLong來改變創建之后的窗口類的參數?例如?光標,?鼠標,?畫刷?等等。

在單文檔的應用程序中,?在CMainFrame類中只可以改變Icon?調用:

在OnCreate函數中

SetClassLong(m_hWnd,?GCL_HICON,?(LONG)LoadIcon(NULL,?IDI_QUESTION));

可以改變application的icon。

?

在VIEW類中改變brush?cursor?background。

在view類中調用

SetClassLong(m_hWnd,?GCL_HBRBACKGROUND,?(LONG)GetStockObject(DKGRAY_BRUSH));

改變了VIEW的背景為灰色。

?

實現一個每一秒中自動換Icon的功能。

Precondition?

在resources?中添加3個icon的資源。

?

1.?首先在CMainFrame類中添加一個數組用于存放資源的句柄。

???在類中添加?HICON?m_hIcon[3];?的一個數組。

2.?在CMainFrame?函數中加載Icon用LoadIcon這個函數。

?

???HICON?LoadIcon( ??HINSTANCE?hInstance,//?handle?to?application?instance ?? LPCTSTR?lpIconName???//?icon-name?string?or?icon?resource? ??????????????????????? ??//?identifier );

?

???如果用的系統的Icon話,?LoadIcon這函數的第一個參數必須為NULL。

???如果用的是自己定義的Iicon的話,?第一個參數是這個應用程序的一個實例句柄。?第二參數是一個是icon的icon-name?string?可以通過MAKEINTRESOURCE這個宏把資源的ID號轉換為資源的字符串名字。

?

LPTSTR?MAKEINTRESOURCE( ??WORD?wInteger?//?integer?to?convert );

?

???得到應用程序實例句柄我們可以通過幾種方法:

???第一種:?AfxGetInstanceHandle()?函數獲得當前應用程序的實例句柄。

???第二種:?因為CStyleApp這個類是從CWinApp這個類中繼承過來的所以繼承了m_hInstance?這個變量,?這個變量就是應用程序的實例句柄。因為MFC在全局中建立了一個CStyleApp中變量?theApp?如果在CMainFrame中得到這個變量就可以得到應用程序的實例句柄。?在CMainFrame中用到全局變量需要聲明這個變量?添加extern?CStyleApp?theApp;?這樣就在CMainFrame中用theApp了。

theApp.m_hInstance.

???第三種:?CWinApp*?AfxGetApp(?);?返回的是一個CWinApp的指針。這樣可以調用它的實例句柄。

?

3.?設置一個定時器在OnCreate中

我們這里調用的是CWND中的定時器。??

?UINT?SetTimer(?UINT?nIDEvent,?UINT?nElapse,?void?(CALLBACK?EXPORT*?lpfnTimer)(HWND,?UINT,?UINT,?DWORD)?);

第一個參數?定時器的ID?第二個參數是設置的時間?第三個參數是處理函數,?如果設置為NULL?發送WM_TIME消息讓消息處理系統調來處理。

???CWnd::SetTimer(1,?1000,?NULL);

?

4.?在CMainFrame類中添加一個WM_TIME的消息處理函數。

?

???static?int?index?=?1;

SetClassLong(m_hWnd,?GCL_HICON,?(LONG)m_hIcons[index]);

index?=?++index?%?3;

這樣就可以定義出一個會隨時間改變的ICON。

?

工具欄的編程???ToolBar

工具欄在resource中添加一個工具欄Item它的ID和menu中的菜單中的一個菜單的Id一樣,?那么這個工具欄的Item就代表著那個菜單。

E.g

在resourcesiView中在幫助的下面添加一個菜單,?叫TEST?它的ID叫ID_TEST?并且建立對應的command消息響應函數,彈出對話框。

在resourcesView的ToolBar中建立一個Item他的ID?也叫ID_TEST?這樣她們就關聯起來了啊。

Click兩個都是一樣的。

?

添加一個自己的工具欄

在MSDN中查看CToolBar?提供了兩種創建工具欄的方法

1.?首先在resourcesView中創建一個自己的ToolBar,?ToolBar上的Item自己設定。

2.?在CMainFrame中添加一個CToolBar的類成員,?構造一個CToolBar的變量。

3.?調用CToolBar的Create?或者CteateEX??參考MSDN

???可以參考CMainFrame中構造ToolBar的方法。

?

if?(!m_wndToolBar.CreateEx(this,?TBSTYLE_FLAT,?WS_CHILD?|?WS_VISIBLE?|?CBRS_TOP

|?CBRS_GRIPPER?|?CBRS_TOOLTIPS?|?CBRS_FLYBY?|?CBRS_SIZE_DYNAMIC)?||

!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0("Failed?to?create?toolbar/n");

return?-1;??????//?fail?to?create

}

4.??調用LoadToolBar這個函數加載資源。

5.?調用CToolBar的成員函數EnableDocking(CBRS_ALIGN_ANY);設置?這個對象是可以停靠的。?如果不設置這個那么工具欄將不可以懸浮。

6.?再調用CMainFrame::EnableDocking(CBRS_ALIGN_ANY);設置框架類可以被停靠。?

7.?最后在調用CMainFrame中的函數DockControlBar(&m_wndToolBar);停靠工具欄。

8.?我們還可以通過在菜單欄上設置一個Item并且設置command消息處理函數。

在處理函數中寫上

if(m_toolBar.IsWindowVisible())

{

????m_toolBar.ShowWindow(SW_HIDE);

}

else

{

m_toolBar.ShowWindow(SW_SHOW);

}

CWnd::IsWindowVisible?當有WS_VISIBLE的時候?返回TRUE.用IsWindowVisible來返回ToolBar是不是可見的。

?

當我調用這個處理的時候?點擊菜單里的Item來顯示或者隱藏工具欄。但是發現雖然ToolBar消失了,?但是這個工具條還在。這個時候工具欄的停靠位子有所變化,?這個時候需要調用

CFrameWnd::RecalcLayout?函數。?

void?RecalcLayout(?BOOL?bNotify?=?TRUE?);

在上面的程序后面接上

RecalcLayout();

當把工具欄拖出來,?處于浮空的ToolBar的時候發現,?然后點擊菜單來顯示或者隱藏ToolBar發現?當浮空的時候ToolBar的工具條不會隱藏。?這個時候我們還需要調用一個函數

DockControlBar(&m_toolBar);

?

顯示或隱藏工具欄的第二種方法

這個時候調用一個函數

ShowControlBar(&m_toolBar,?!m_toolBar.IsWindowVisible(),?FALSE);??具體調用參見MSDN。?ShowControlBar是CFrameWnd框架類的一個函數。

?

9.?我們還需要標記菜單的Item。當選中是標記,?當隱藏時取消標記。這個時候我們需要對這個Item的?UPDATE_COMMAND_UI進行響應。建立消息響應來標記活隱藏標記。?

調用CCmdUI的SetCheck();這個函數。來標記或者取消標記。

pCmdUI->SetCheck(m_toolBar.IsWindowVisible());?具體用法參見MSDN。

?

狀態欄的編寫

1.??首先construct?一個CStatusBar的對象。

2.??然后調用變量的Create函數把狀態欄窗口和一個CStatusBar的對象綁定。

?

CStatusBar::Create

BOOL?Create(?CWnd*?pParentWnd,?DWORD?dwStyle?=?WS_CHILD?|?WS_VISIBLE?|?CBRS_BOTTOM,?UINT?nID?=?AFX_IDW_STATUS_BAR?);

在MFC中是這樣調用的:

if?(!m_wndStatusBar.Create(this)?||?!m_wndStatusBar.SetIndicators(indicators,

?sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed?to?create?status?bar/n");

return?-1;??????//?fail?to?create

}

m_wndStausBar.Create(this),?其他的參數都用默認的參數。?后來條用m_wndStatusBar.Setindicators(indicators,?sizeof(indicators)/sizeof(UINT));

Indicators?是一個數組儲存字符串ID和每一個指示符。?后面一個參數是數組里面的數是多少個。

可以添加indicator?在數組中,?首先在String?Table?中添加字符串ID?,?然后把字符串ID添加在indicators的數組里面。這樣就可以在狀態欄中顯示了。?

有三種方法更新狀態欄上的字符。

1.?Call?CWnd::SetWindowText?to?update?the?text?in?pane?0?only.

2.?Call?CCmdUI::SetText?in?the?status?bar’s?ON_UPDATE_COMMAND_UI?handler.

3.?Call?SetPaneText?to?update?the?text?for?any?pane.

?

我們可以把系統當前時間顯示在狀態欄上。

這個時候需要用到?CTime

?CTime?t?=?CTime::GetCurrentTime();

CString?timeStr?=?t.Format("%H:%M:%S");

格式輸出到一個字符串中。?

然后調用?m_wndStatusBar.SetPaneText(1,?timeStr);

第一個參數是索引Index?of?the?pane?whose?text?is?to?be?set。

timeStr是要顯示的字符串了。

如果不知道要顯示的索引,?我們可用調用m_wndStatusBar的一個成員函數CommandToIndex(IDS_TIMER);?括號里面的參數是表示要顯示的字符串ID。

?

運行程序,?我們會發現時鐘的秒不能顯示。?這個是因為狀態欄空間不夠所以不能完全顯示內容。?

我們可以調用SetPaneInfo();

CStatusBar::SetPaneInfo

void?SetPaneInfo(?int?nIndex,?UINT?nID,?UINT?nStyle,?int?cxWidth?);

?

?函數改變狀態欄空間大小。

?

為了獲得字符串的顯示寬度,?我們需要調用GetTextExtent(Cstring?str);來返回字符創的空間大小,?CSize。

CClientDC?dc(this);

CSize?sz?=?dc.GetTextExtent(timeStr);

之后再調用SetPaneText();來顯示內容

?

這個時候發現時間是不動的。?需要動,?要把剛剛這段代碼放到SetTimer的響應函數中不停調用顯示時間。?

?

創建一個進度欄

進度欄的類是CProgressCtrl。?定義一個變量,?并且調用Create初始化一個進度欄。

?

CProgressCtrl::Create

BOOL?Create(?DWORD?dwStyle,?const?RECT&?rect,?CWnd*?pParentWnd,?UINT?nID?);

第一個參數是一個窗口類,?E.G??WS_CHILD?|?WS_VISIBLE?|?PBS_SMOOTH?

第二個參數是一個矩形區域。

?

CProgressCtrl?m_progressCtrl;

m_progressCtrl.SetPos(50); 設置到中間。?

?

如果我們想把這個矩形區域顯示在狀態欄里。?

?

首相我們在CMainFrame類中編寫這樣一段程序

CRect?rect;

m_wndStatusBar.GetItemRect(2,?&rect);

m_progressCtrl.Create(WS_CHILD|?WS_VISIBLE|?PBS_SMOOTH,?rect,

&m_wndStatusBar,?1);

注意這里的&m_wndStatusBar是進度條的父窗口。?在View類中創建進度條時,?父類窗口就是this,?代表這個對象的指針。

?

運行程序發現進度條并沒有出現,?我們在CRect?rect?;?這里設置斷點,?運行函數,?看斷點的值發現rect的值是一個無效的值,?這個時候我們猜想,?在OnCreat?結束錢狀態欄還沒有初始化好。?這樣我們可以在OnCreate之后調用一個函數來處理進度條。

我們可以自己定義一個消息,在OnCreate中把這個消息投遞到消息隊列中,來處理這個函數。

首先我先定義一個消息,?在window中消息都是用一個整數來表示的,在CMainFrame的頭文件中添加一個消息。?#define?UM_PROGRESS?WM_USER+1

因為window的很多消息已經占用了很多的整數,?我們胡亂定義很可可能和系統沖突,?WM_USER以下的是系統消息保留的。?以上的可以是用戶自己定義的。這樣我們就定義了一個UM_PROGRESS?的消息。添加完這個消息后,?要有相應的消息響應函數來處理這個消息。

protected:

//{{AFX_MSG(CMainFrame)

afx_msg?int?OnCreate(LPCREATESTRUCT?lpCreateStruct);

afx_msg?void?OnTimer(UINT?nIDEvent);

afx_msg?void?OnTest();

afx_msg?void?OnAppendToolbar();

afx_msg?void?OnUpdateAppendToolbar(CCmdUI*?pCmdUI);

afx_msg?void?OnPaint();

//}}AFX_MSG

先要在頭文件的這段代碼后面添加

??afx_msg?void?OnProgress();

DECLARE_MESSAGE_MAP()

?

參考MFC的程序;

然后在。CPP文件中

BEGIN_MESSAGE_MAP(CMainFrame,?CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

ON_WM_CREATE()

ON_WM_TIMER()

ON_COMMAND(ID_TEST,?OnTest)

ON_COMMAND(ID_APPEND_TOOLBAR,?OnAppendToolbar)

ON_UPDATE_COMMAND_UI(ID_APPEND_TOOLBAR,?OnUpdateAppendToolbar)

ON_WM_PAINT()

//}}AFX_MSG_MAP

ON_MESSAGE(UM_PROGRESS,?OnProgress)

END_MESSAGE_MAP()

消息響應函數是通過?ON_MESSAGE()?把消息和消息處理函數關聯起來的。

?

最后在添加消息處理函數

Void?CMainFrame::OnProgress()

?

CRect?rect;

m_wndStatusBar.GetItemRect(2,?&rect);

m_progressCtrl.Create(WS_CHILD|?WS_VISIBLE|?PBS_SMOOTH,?rect,

&m_wndStatusBar,?1);

?

在這個函數中處理進度條。在OnCreate函數中用PostMessage();

不能用SendMessage();?因為?SendMessage是直接調用了處理函數,?這個時候狀態欄還沒有處理好。?

?

現在運行應用程序,?這個時候progress顯示在狀態欄上,?但是當我們拉伸或者縮放的時候進度欄?不再第二個狀態欄上的時候而是在別的地方?這是為什么呢??

每當窗口的尺寸變化的時候就會重繪發送ON_PAIN這個消息我們可以創建響應函數,?在這個函數中編寫上面的程序。

當改變尺寸的時候會當初dialog錯誤,?這是因為每當發送一個ON_PAIN消息函數的時候都會Create一個進度欄,?所照成了錯誤。應該判斷是否已經創建沒有創建的時候創建,?創建了移動窗口。

修改程序為一下:

CRect?rect;

m_wndStatusBar.GetItemRect(2,?&rect);

if(m_progressCtrl.m_hWnd?==?NULL)

m_progressCtrl.Create(WS_CHILD|?WS_VISIBLE|?PBS_SMOOTH,?rect,

&m_wndStatusBar,?1);

else

m_progressCtrl.MoveWindow(rect);

?

如果要進度欄里的進度增加的話,?我們可以調用CProgressCtrl類的一個StepIt函數來增長,?把發在OnTimer();?里面每次調用就會發送一個OnPaint函數來重繪進度欄。?

?

現在我們想在在狀態欄上顯示當前鼠標的位置,?在View類中添加ON_MOUSEMOVE處理函數。

CString?pointStr;

pointStr.Format("x=%d?y=%d",?point.x,?point.y);

((CMainFrame*)GetParent())->m_wndStatusBar.SetPaneText(0,?pointStr);

運行程序顯示出位置。因為狀態欄是框架類的,?所以首先要先獲得框架類的指針,?通過GetParent()?這個函數來獲得,?轉換為CMainFrame指針類型。

需要在View中加入頭文件“MainFrm.h”

或者調用?((CMainFrame*)GetParent())->SetMessageText(pointStr);

?

也可以這樣

((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(pointStr);

GetMessageBar()是一個CMainFrame類的函數,?無需知道狀態欄的變量。

?

創建啟動畫面

在菜單上點擊工程->添加到工程->組件和空間-?>Visual?C++?components->solash?Screen?->insert.


總結

以上是生活随笔為你收集整理的改变窗口的外观和大小的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。