如何有效地使用對話框

本文轉自:http://www.vckbase.com/document/viewdoc/?id=419

Q:如何在對話框中加入工具條在 OnInitDialog 中加入下面代碼:

BOOL CYourDlg::OnInitDialog()
{
       CDialog::OnInitDialog();	

       // Create the toolbar. To understand the meaning of the styles used, you 
       // can take a look at the MSDN for the Create function of the CToolBar class.
	   
       ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS |CBRS_FLYBY | CBRS_BORDER_BOTTOM);

      // I have assumed that you have named your toolbar''s resource as IDR_TOOLBAR1.
      // If you have given it a different name, change the line below to accomodate 
      // that by changing the parameter for the LoadToolBar function.
	  
      ToolBar.LoadToolBar(IDR_TOOLBAR1);
  
      CRect rcClientStart;
      CRect rcClientNow;
      GetClientRect(rcClientStart);


      // To reposition and resize the control bar

     RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,0, reposQuery, rcClientNow);
     CPoint ptOffset(rcClientNow.left - rcClientStart.left,rcClientNow.top-rcClientStart.top);

     CRect rcChild;
     CWnd* pwndChild = GetWindow(GW_CHILD);

     while (pwndChild)
     {
       pwndChild->GetWindowRect(rcChild);
       ScreenToClient(rcChild);
       rcChild.OffsetRect(ptOffset);
       pwndChild->MoveWindow(rcChild, FALSE);
       pwndChild = pwndChild->GetNextWindow();
     } 
	  CRect rcWindow;
     GetWindowRect(rcWindow);
     rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
     rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
     MoveWindow(rcWindow, FALSE);	

     // And position the control bars
     RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
  
     return TRUE;  // return TRUE  unless you set the focus to a control
  }

Q:如何改變對話框的形狀?

可用下面一些函數:
CreatePolygonRgn
CreateRectRgn
CreateRoundRectRgn 等.

  CRgn m_rgn;  // Put this in your dialog''s header file. i.e. a member variable

  // This Gets the size of the Dialog: This piece of code is to be placed in the
  // OnInitDialog Function of your dialog.

  CRect rcDialog
  GetClientRect(rcDialog);

  // The following code Creates the area and assigns it to your Dialog
  m_rgn.CreateEllipticRgn(0, 0, rcDialog.Width(), rcDialogHeight());
  SetWindowRgn(GetSafeHwnd(), (HRGN) m_rgn, TRUE);

Q:如何實現非客戶區移動?

可用下面二種方法

// Handler for WM_LBUTTONDOWN message

  void CYourDialog::OnLButtonDown(UINT nFlags, CPoint point)
  {
     CDialog::OnLButtonDown(nFlags, point);
     PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
  }

  // Handler for WM_NCHITTEST message

  LONG CYourDialog::OnNcHitTest( UINT uParam, LONG lParam )
  {  
     int xPos = LOWORD(lParam);
     int yPos = HIWORD(lParam);
     UINT nHitTest = CDialog::OnNcHitTest(CSize(xPos, yPos));
     return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;
  }


Q:如何使對話框初始爲最小化狀態?

在 OnInitDialog 中加入下面代碼:

SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, NULL);

Q:如何限定對話框大小範圍?

在 WM_SIZING中加入下面代碼:

void CYourDialog::OnSizing(UINT fwSide, LPRECT pRect) 
  {
     if(pRect->right - pRect->left <=200)
     	pRect->right = pRect->left + 200;
	
     if(pRect->bottom - pRect->top <=200)
     	pRect->bottom = pRect->top + 200;

     CDialog::OnSizing(fwSide, pRect);
  }

Q:如何在對話框中加入狀態條?

定義 CStatusBar 變量:

CStatusBar m_StatusBar;

定義狀態條指定狀態:

static UINT BASED_CODE indicators[] =
  {
     ID_INDICATOR_CAPS,
     ID_INDICATOR_NUM
  };

在 OnInitDialog 中加入下面代碼:

  m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,AFX_IDW_STATUS_BAR);
 
  // Set the indicators namely caps and nums lock status
  m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));

  CRect rect;
  GetClientRect(&rect);
		
  m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/2);
  m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH ,rect.Width()/2);

  RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_NUM);

  m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180));

 

1. 如何有效地使初始窗口不顯示
當我們想讓窗口初始時不顯示時,通常會用ShowWindow(SW_HIDE) ,但實際上還是在啓動是可以看到窗口一閃而過的痕跡。所以,可以使用下面的方法來實現它:
(1.1)先在構造函數中設置布樂變量 visible值爲false.

visible = false;

(1.2)重載 WM_WINDOWPOSCHANGING,並添加下面代碼:

void CTest_deleteDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
{
    if(!visible)
        lpwndpos->flags &= ~SWP_SHOWWINDOW;

    CDialog::OnWindowPosChanging(lpwndpos);
}

(1.3)然後設布爾visible變量值爲true,並在要顯示窗口時,再用ShowWindow(SW_SHOW)既可。

visible = true;
ShowWindow(SW_SHOW);

2. 對話框的全屏顯示
對話框的全屏顯示可以在OnInitDialog()中用 SetWindowPos 和 HWND_TOPMOST 來實現對話框的重新大小。

BOOL CFullScrDlgDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    //...

    int cx, cy; 
    HDC dc = ::GetDC(NULL); 
    cx = GetDeviceCaps(dc,HORZRES) + 
        GetSystemMetrics(SM_CXBORDER); 
    cy = GetDeviceCaps(dc,VERTRES) +
        GetSystemMetrics(SM_CYBORDER); 
    ::ReleaseDC(0,dc); 

    //去除標題和邊框
    SetWindowLong(m_hWnd, GWL_STYLE, 
        GetWindowLong(m_hWnd, GWL_STYLE) & 
    (~(WS_CAPTION | WS_BORDER))); 

    // 置對話框爲最頂端並擴充到整個屏幕
    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 
        -(GetSystemMetrics(SM_CXBORDER)+1), 
        -(GetSystemMetrics(SM_CYBORDER)+1), 
        cx+1,cy+1, SWP_NOZORDER); 

    //...

    return TRUE; 
}

3. 如何在2K/xp下使窗口獲取焦點
在2K/XP下我們可以用 AttachThreadInput 和SetForegroundWindow來有效的獲取焦點。

//捕捉並設置當前焦點窗口爲我們的窗口
AttachThreadInput(
    GetWindowThreadProcessId(
        ::GetForegroundWindow(),NULL),
    GetCurrentThreadId(),TRUE);

//置我們的爲焦點窗口
SetForegroundWindow();
SetFocus(); 

//釋放thread
AttachThreadInput(
    GetWindowThreadProcessId(
        ::GetForegroundWindow(),NULL),
    GetCurrentThreadId(),FALSE);

4. 使你的對話框位於最頂端
可以直接在 OnInitDialog()中用SetWindowPos來實現。

SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

5. 如何動態放大/縮小對話框
還是可以用SetWindowPos或MoveWindow來實現它。

void CTest_deleteDlg::OnMakeSmall() 
{
    SetWindowPos(NULL,0,0,200,200,SWP_NOZORDER|SWP_NOMOVE);	
}

void CTest_deleteDlg::OnExpand() 
{
    SetWindowPos(NULL,0,0,500,300,SWP_NOZORDER|SWP_NOMOVE);		
}

或:

//伸、縮在IDC_DYCREDITS和IDC_COPYRIGHT兩STATIC控件間,做爲分隔線
BOOL CAbout::OnInitDialog() 
{
	CDialog::OnInitDialog();
//"關於"對話框中對話框可收縮效果
	CRect Rect1,Rect2; 							     //對話框收縮時大小		
	
	GetDlgItem(IDC_DYCREDITS)->GetWindowRect(Rect1); 
	GetDlgItem(IDC_COPYRIGHT)->GetWindowRect(Rect2); 
	m_nReducedHeight = Rect1.Height()+(Rect1.top -Rect2.bottom)/2; //收縮後窗體高度
	dlgRect.bottom -= (Rect1.Height()+(Rect1.top -Rect2.bottom)/2); 
	MoveWindow(&dlgRect);				              //如果要顯示對話框起始動態效果的話,不能使用該句

	m_bVertical=false;                                //默認收縮對話框
}
// ---------------------------------------------------------
//	名稱: OnMore
//	功能: 是否允許顯示
//	變量: 無
//	返回: 無
//	編寫: 徐景周,2002.4.8
// ---------------------------------------------------------
void CAbout::OnMore() 
{
	m_bVertical = !m_bVertical; 
	
	if(m_bVertical == FALSE)	//不顯示
	{ 
		SetDlgItemText(ID_MORE,_T("更多>>"));

		SizeWindow(m_nReducedHeight,true);

//		m_DyCredits.EndScrolling();              //停止滾動
	} 
	else						//顯示
	{ 
		SetDlgItemText(ID_MORE,_T("<<隱藏"));

		SizeWindow(m_nReducedHeight,false);

		m_DyCredits.StartScrolling();			//開始滾動
	} 
	
	UpdateWindow(); 
}

// ---------------------------------------------------------
//	名稱: SizeWindow
//	功能: 伸展或收縮對話框    
//	變量: ReduceHeight-收縮高度,bExtend-是否伸展
//	返回: 無
//	編寫: 徐景周,2002.4.8
// ---------------------------------------------------------	
void CAbout::SizeWindow(int ReduceHeight, bool bExtend)
{
	CRect rc;
	GetWindowRect(&rc);
	if(bExtend)
	{
		for (int i= 0; i < ReduceHeight; i++)
		{
			rc.bottom--;
			MoveWindow(&rc);
		}
	}
	else
	{
		for (int i= 0; i < ReduceHeight; i++)
		{
			rc.bottom++;
			MoveWindow(&rc);
		}
	}
}

6. 如何讓對話框回到屏幕中來
當對話框被拖離屏幕時,可用下面代碼使其回到屏幕中。

SendMessage(DM_REPOSITION);

注:它必須是頂端窗口且不是child窗口。

7. 如何給對話框添加或去掉最大/最小化按鈕
在OnCreate()或OnInitDialog() 改變其顯示風格既可。

int CTest_deleteDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;	
    // TODO: Add your specialized creation code here
    SetWindowLong(this->m_hWnd,GWL_STYLE,
        GetWindowLong(this->m_hWnd,GWL_STYLE) | 
            WS_MINIMIZEBOX | WS_MAXIMIZEBOX);	
    return 0;
}

或用:

ModifyStyle (NULL, WS_MAXIMIZEBOX);

8. 改變鼠標指針
可以在OnSetCursor中實現.

BOOL CTest_deleteDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
    // TODO: Add your message handler code here and/or call default
    SetCursor(AfxGetApp()->LoadStandardCursor(IDC_UPARROW));
    // Now we return instead of calling the base class
    return 0;	
    // return CDialog::OnSetCursor(pWnd, nHitTest, message);
}

9. 改變對話框的前景和背景色
可以在InitInstance()中實現。

//紅色背景、綠色前景
SetDialogBkColor(RGB(255,0,0),RGB(0,255,0)); 

10. 在任務條上不顯示圖標
先從CWinApp繼承類中建立一個不顯示的頂級窗口.

CFrameWnd *abc=new CFrameWnd();
abc->Create(0,0,WS_OVERLAPPEDWINDOW);
CNoTaskBarIconDlg dlg(abc);
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
delete abc;

在 OnInitDialog中修改顯示風格 WS_EX_APPWINDOW.

BOOL CNoTaskBarIconDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    ModifyStyleEx(WS_EX_APPWINDOW,0);

    SetIcon(m_hIcon, TRUE);  // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon
	
    // TODO: Add extra initialization here
	
    return TRUE;  // return TRUE  unless you set the focus to a control
}

11. 加入上、下文幫助
在 OnInitDialog 修改顯示風格,加入上、下文HLP幫助顯示.

BOOL HelpDialog::OnInitDialog() 
{

    ModifyStyleEx(0, WS_EX_CONTEXTHELP);
    return CDialog::OnInitDialog();
}

重載OnHelpInfo(...),用顯示相關幫助信息

BOOL HelpDialog::OnHelpInfo(HELPINFO* pHelpInfo) 
{
    short state = GetKeyState (VK_F1);
    if (state < 0)   // F1 key is down, get help for the dialog
        return CDialog::OnHelpInfo(pHelpInfo);
    else
    {    // F1 key not down, get help for specific control
        if (pHelpInfo->dwContextId)
            WinHelp (pHelpInfo->dwContextId, 
                HELP_CONTEXTPOPUP);
        return TRUE;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章