⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtl for mfc programmers, part vii.mht

📁 大家知道wtl是window UI库
💻 MHT
📖 第 1 页 / 共 5 页
字号:
window=20
      classes. There are three classes, although you will normally only =
use one:=20
      <CODE>CSplitterImpl</CODE>, <CODE>CSplitterWindowImpl</CODE>, and=20
      <CODE>CSplitterWindowT</CODE>. The classes and their basic methods =
are=20
      explained below.</P>
      <H3><A name=3Dsplitclasses></A>Classes</H3>
      <P><CODE>CSplitterImpl</CODE> is a template class that takes two =
template=20
      parameters, a window interface class name and a boolean that =
indicates the=20
      splitter orientation: <CODE><SPAN =
class=3Dcpp-keyword>true</SPAN></CODE> for=20
      vertical, <CODE><SPAN class=3Dcpp-keyword>false</SPAN></CODE> for=20
      horizontal. <CODE>CSplitterImpl</CODE> has almost all of the=20
      implementation for a splitter, and many methods are overridable so =
you can=20
      provide custom drawing of the split bar or other effects.=20
      <CODE>CSplitterWindowImpl</CODE> derives from =
<CODE>CWindowImpl</CODE> and=20
      <CODE>CSplitterImpl</CODE>, but doesn't have much code. It has an =
empty=20
      <CODE>WM_ERASEBKGND</CODE> handler, and a <CODE>WM_SIZE</CODE> =
handler=20
      that resizes the splitter window.</P>
      <P>Finally, <CODE>CSplitterWindowT</CODE> derives from=20
      <CODE>CSplitterImpl</CODE> and provides a window class name, =
<CODE><SPAN=20
      class=3Dcpp-string>"WTL_SplitterWindow"</SPAN></CODE>. There are =
two=20
      typedefs that you will normally use instead of the three above =
classes:=20
      <CODE>CSplitterWindow</CODE> for a vertical splitter, and=20
      <CODE>CHorSplitterWindow</CODE> for a horizontal splitter.</P>
      <H3><A name=3Dcreatingsplitter></A>Creating a splitter</H3>
      <P>Since <CODE>CSplitterWindow</CODE> derives from=20
      <CODE>CWindowImpl</CODE>, you create a splitter just like any =
other child=20
      window. Since the splitter will exist for the lifetime of the main =
frame,=20
      you can add a <CODE>CSplitterWindow</CODE> member variable in=20
      <CODE>CMainFrame</CODE>. In <CODE>CMainFrame::OnCreate()</CODE>, =
you=20
      create the splitter as a child of the frame, then set the splitter =
as the=20
      main frame's client window:</P><PRE>LRESULT CMainFrame::OnCreate ( =
LPCREATESTRUCT lpcs )
{
<SPAN class=3Dcpp-comment>// ...</SPAN>
<SPAN class=3Dcpp-keyword>const</SPAN> DWORD dwSplitStyle =3D WS_CHILD | =
WS_VISIBLE |=20
                             WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
            dwSplitExStyle =3D WS_EX_CLIENTEDGE;
=20
    m_wndSplit.Create ( *<SPAN class=3Dcpp-keyword>this</SPAN>, =
rcDefault, NULL,=20
                        dwSplitStyle, dwSplitExStyle );
=20
    m_hWndClient =3D m_wndSplit;
}</PRE>
      <P>After creating the splitter, you can assign windows to its =
panes, and=20
      do any other necessary initialization.</P>
      <H3><A name=3Dsplittermethods></A>Basic methods</H3><PRE><SPAN =
class=3Dcpp-keyword>bool</SPAN> SetSplitterPos(<SPAN =
class=3Dcpp-keyword>int</SPAN> xyPos =3D -<SPAN =
class=3Dcpp-literal>1</SPAN>, <SPAN class=3Dcpp-keyword>bool</SPAN> =
bUpdate =3D <SPAN class=3Dcpp-keyword>true</SPAN>)
<SPAN class=3Dcpp-keyword>int</SPAN> GetSplitterPos()</PRE>
      <P>Call <CODE>SetSplitterPos()</CODE> to set the position of the =
splitter=20
      bar. The position is expressed in pixels relative to the top edge =
(for=20
      horizontal splitters) or left edge (for vertical splitters) of the =

      splitter window. You can use the default of -1 to position the =
splitter=20
      bar in the middle, making both panes the same size. You will =
usually pass=20
      <CODE><SPAN class=3Dcpp-keyword>true</SPAN></CODE> for =
<CODE>bUpdate</CODE>,=20
      to resize the two panes accordingly after moving the splitter bar. =

      <CODE>GetSplitterPos()</CODE> returns the current position of the =
splitter=20
      bar, relative to the top or left edge of the splitter =
window.</P><PRE><SPAN class=3Dcpp-keyword>bool</SPAN> =
SetSinglePaneMode(<SPAN class=3Dcpp-keyword>int</SPAN> nPane =3D =
SPLIT_PANE_NONE)
<SPAN class=3Dcpp-keyword>int</SPAN> GetSinglePaneMode()</PRE>
      <P>Call <CODE>SetSinglePaneMode()</CODE> to change the splitter =
between=20
      one-pane and two-pane mode. In one-pane mode, only one pane is =
visible and=20
      the splitter bar is hidden, similar to how MFC dynamic splitters =
work=20
      (although there is no little gripper handle to re-split the =
splitter). The=20
      allowable values for <CODE>nPane</CODE> are: =
<CODE>SPLIT_PANE_LEFT</CODE>,=20
      <CODE>SPLIT_PANE_RIGHT</CODE>, <CODE>SPLIT_PANE_TOP</CODE>,=20
      <CODE>SPLIT_PANE_BOTTOM</CODE>, and <CODE>SPLIT_PANE_NONE</CODE>. =
The=20
      first four indicate which pane to show (for example, passing=20
      <CODE>SPLIT_PANE_LEFT</CODE> shows the left-side pane and hides =
the=20
      right-side pane). Passing <CODE>SPLIT_PANE_NONE</CODE> shows both =
panes.=20
      <CODE>GetSinglePaneMode()</CODE> returns one of those five=20
      <CODE>SPLIT_PANE_*</CODE> values indicating the current =
mode.</P><PRE>DWORD SetSplitterExtendedStyle(DWORD dwExtendedStyle, =
DWORD dwMask =3D <SPAN class=3Dcpp-literal>0</SPAN>)
DWORD GetSplitterExtendedStyle()</PRE>
      <P>Splitter windows have their own style bits that control how the =

      splitter bar moves when the entire splitter window is resized. The =

      available styles are:</P>
      <UL>
        <LI><CODE>SPLIT_PROPORTIONAL</CODE>: Both panes in the splitter =
resize=20
        together=20
        <LI><CODE>SPLIT_RIGHTALIGNED</CODE>: The right pane stays the =
same size=20
        when the entire splitter is resized, and the left pane resizes=20
        <LI><CODE>SPLIT_BOTTOMALIGNED</CODE>: The bottom pane stays the =
same=20
        size when the entire splitter is resized, and the top pane =
resizes=20
      </LI></UL>
      <P>If neither <CODE>SPLIT_PROPORTIONAL</CODE> nor=20
      <CODE>SPLIT_RIGHTALIGNED</CODE>/<CODE>SPLIT_BOTTOMALIGNED</CODE> =
is=20
      specified, the splitter becomes left- or top-aligned. If you pass=20
      <CODE>SPLIT_PROPORTIONAL</CODE> and=20
      <CODE>SPLIT_RIGHTALIGNED</CODE>/<CODE>SPLIT_BOTTOMALIGNED</CODE> =
together,=20
      <CODE>SPLIT_PROPORTIONAL</CODE> takes precedence.</P>
      <P>There is one additional style that controls whether the user =
can move=20
      the splitter bar:</P>
      <UL>
        <LI><CODE>SPLIT_NONINTERACTIVE</CODE>: The splitter bar cannot =
be moved=20
        and does not respond to the mouse </LI></UL>
      <P>The default value of the extended styles is=20
      <CODE>SPLIT_PROPORTIONAL</CODE>.</P><PRE><SPAN =
class=3Dcpp-keyword>bool</SPAN> SetSplitterPane(<SPAN =
class=3Dcpp-keyword>int</SPAN> nPane, HWND hWnd, <SPAN =
class=3Dcpp-keyword>bool</SPAN> bUpdate =3D <SPAN =
class=3Dcpp-keyword>true</SPAN>)
<SPAN class=3Dcpp-keyword>void</SPAN> SetSplitterPanes(HWND hWndLeftTop, =
HWND hWndRightBottom, <SPAN class=3Dcpp-keyword>bool</SPAN> bUpdate =3D =
<SPAN class=3Dcpp-keyword>true</SPAN>)
HWND GetSplitterPane(<SPAN class=3Dcpp-keyword>int</SPAN> nPane)</PRE>
      <P>Call <CODE>SetSplitterPane()</CODE> to assign a child window to =
one=20
      pane of the splitter. <CODE>nPane</CODE> is one of the=20
      <CODE>SPLIT_PANE_*</CODE> values indicating which pane you are =
setting.=20
      <CODE>hWnd</CODE> is the window handle of the child window. You =
can assign=20
      child windows to both panes at once with =
<CODE>SetSplitterPanes()</CODE>.=20
      You will usually take the default value of <CODE>bUpdate</CODE>, =
which=20
      tells the splitter to immediately resize the child windows to fit =
in the=20
      panes. You can get the <CODE>HWND</CODE> of the window in a pane =
with=20
      <CODE>GetSplitterPane()</CODE>. If no window has been assigned to =
a pane,=20
      <CODE>GetSplitterPane()</CODE> returns NULL.</P><PRE><SPAN =
class=3Dcpp-keyword>bool</SPAN> SetActivePane(<SPAN =
class=3Dcpp-keyword>int</SPAN> nPane)
<SPAN class=3Dcpp-keyword>int</SPAN> GetActivePane()</PRE>
      <P><CODE>SetActivePane()</CODE> sets the focus to one of the =
windows in=20
      the splitter. <CODE>nPane</CODE> is one of the =
<CODE>SPLIT_PANE_*</CODE>=20
      values indicating which pane you are setting as the active one. It =
also=20
      sets the default active pane (explained below).=20
      <CODE>GetActivePane()</CODE> checks the window with the focus, and =
if that=20
      window is a pane window or a child of a pane window, returns a=20
      <CODE>SPLIT_PANE_*</CODE> value indicating which pane. If the =
window with=20
      the focus is not a child of a pane, <CODE>GetActivePane()</CODE> =
returns=20
      <CODE>SPLIT_PANE_NONE</CODE>.</P><PRE><SPAN =
class=3Dcpp-keyword>bool</SPAN> ActivateNextPane(<SPAN =
class=3Dcpp-keyword>bool</SPAN> bNext =3D <SPAN =
class=3Dcpp-keyword>true</SPAN>)</PRE>
      <P>If the splitter is in single-pane mode, the focus is set to the =
visible=20
      pane. Otherwise, <CODE>ActivateNextPane()</CODE> checks the window =
with=20
      the focus with <CODE>GetActivePane()</CODE>. If a pane (or child =
of a=20
      pane) has the focus, the splitter sets the focus to the other =
pane.=20
      Otherwise, <CODE>ActivateNextPane()</CODE> activates the left/top =
pane if=20
      <CODE>bNext</CODE> is true, or the right/bottom pane if bNext is=20
false.</P><PRE><SPAN class=3Dcpp-keyword>bool</SPAN> =
SetDefaultActivePane(<SPAN class=3Dcpp-keyword>int</SPAN> nPane)
<SPAN class=3Dcpp-keyword>bool</SPAN> SetDefaultActivePane(HWND hWnd)
<SPAN class=3Dcpp-keyword>int</SPAN> GetDefaultActivePane()</PRE>
      <P>Call <CODE>SetDefaultActivePane()</CODE> with either a=20
      <CODE>SPLIT_PANE_*</CODE> value or window handle to set that pane =
as the=20
      default active pane. If the splitter window itself gets the focus, =
via a=20
      <CODE>SetFocus()</CODE> call, it in turn sets the focus to the =
default=20
      active pane. <CODE>GetDefaultActivePane()</CODE> returns a=20
      <CODE>SPLIT_PANE_*</CODE> value indicating the current default =
active=20
      pane.</P><PRE><SPAN class=3Dcpp-keyword>void</SPAN> =
GetSystemSettings(<SPAN class=3Dcpp-keyword>bool</SPAN> bUpdate)</PRE>
      <P><CODE>GetSystemSettings()</CODE> reads various system settings =
and sets=20
      data members accordingly. The splitter calls this automatically in =

      <CODE>OnCreate()</CODE>, so you don't have to call it yourself. =
However,=20
      your main frame should handle the <CODE>WM_SETTINGCHANGE</CODE> =
message=20
      and pass it along to the frame; <CODE>CSplitterWindow</CODE> calls =

      <CODE>GetSystemSettings()</CODE> in its =
<CODE>WM_SETTINGCHANGE</CODE>=20
      handler. Pass true for <CODE>bUpdate</CODE> to have the splitter =
redraw=20
      itself using the new settings.</P>
      <H3><A name=3Dsplitdata></A>Data members</H3>
      <P>Some other splitter features are controlled by setting public =
members=20
      of <CODE>CSplitterWindow</CODE>. These are all reset when=20
      <CODE>GetSystemSettings()</CODE> is called.</P>
      <P><CODE>m_cxySplitBar</CODE>: Controls the width (for vertical =
splitters)=20
      or height (for horizontal splitters) of the splitter bar. The =
default is=20
      the value returned by =
<CODE>GetSystemMetrics(SM_CXSIZEFRAME)</CODE> (for=20
      vertical splitters) or =
<CODE>GetSystemMetrics(SM_CYSIZEFRAME)</CODE> (for=20
      horizontal splitters).</P>
      <P><CODE>m_cxyMin</CODE>: Controls the minimum width (for vertical =

      splitters) or height (for horizontal splitters) of each pane. The =
splitter=20
      will not allow you to drag the bar if it would make either pane =
smaller=20
      than this number of pixels. The default is 0 if the splitter =
window has=20
      the <CODE>WS_EX_CLIENTEDGE</CODE> extended style. Otherwise, the =
default=20
      is <CODE><SPAN=20
      class=3Dcpp-literal>2</SPAN>*GetSystemMetrics(SM_CXEDGE)</CODE> =
(for=20
      vertical splitters) or <CODE><SPAN=20
      class=3Dcpp-literal>2</SPAN>*GetSystemMetrics(SM_CYEDGE)</CODE> =
(for=20
      horizontal splitters).</P>
      <P><CODE>m_cxyBarEdge</CODE>: Controls the width (for vertical =
splitters)=20
      or height (for horizontal splitters) of the 3D edge drawn on the =
sides of=20
      the splitter bar. The default value is the opposite of the default =
of=20
      <CODE>m_cxyMin</CODE>.</P>
      <P><CODE>m_bFullDrag</CODE>: If true, the panes resize as the =
splitter bar=20
      is dragged. If false, only a ghost image of the splitter bar is =
drawn, and=20
      the panes don't resize until the user releases the splitter bar. =
The=20
      default is the value returned by=20
      <CODE>SystemParametersInfo(SPI_GETDRAGFULLWINDOWS)</CODE>.=20
      <H2><A name=3Dstartsample></A>Starting the Sample Project</H2>
      <P>Now that we have the basics out of the way, let's see how to =
set up a=20
      frame window that contains a splitter. Start a new project with =
the WTL=20
      AppWizard. On the first page, leave <I>SDI Application</I> =
selected and=20
      click Next. On the second page, uncheck <I>Toolbar</I>, then =
uncheck=20
      <I>Use a view window</I> as shown here:</P>
      <P><IMG height=3D387 alt=3D" [AppWizard pg 2 - 22K] "=20
      src=3D"http://www.codeproject.com/wtl/WTL4MFC7/appwiz.png" =
width=3D477=20
      align=3Dbottom border=3D0></P>
      <P>We don't need a view window because the splitter and its panes =
will=20
      become the "view." In <CODE>CMainFrame</CODE>, add a=20
      <CODE>CSplitterWindow</CODE> member:</P><PRE><SPAN =
class=3Dcpp-keyword>class</SPAN> CMainFrame : <SPAN =
class=3Dcpp-keyword>public</SPAN> ...
{
<SPAN class=3Dcpp-comment>//...</SPAN>
<SPAN class=3Dcpp-keyword>protected</SPAN>:
    CSplitterWindow  m_wndVertSplit;
};</PRE>
      <P>Then in <CODE>OnCreate()</CODE>, create the splitter and set it =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -