File Splitter Download For Windows 7

0 views
Skip to first unread message

Roxann Monier

unread,
Jan 24, 2024, 9:46:00 PM1/24/24
to profbackresang

Check out Large Text File Viewer, it's great for things like this. Most archivers and splitters will separate the file into pieces which cannot be used to read each piece of data independently and properly, you need to extract them all to get the file back.

file splitter download for windows 7


Download Zip https://t.co/ILMHFMzDzq



Splitter windows have been a popular UI element since Explorer debuted in Windows 95, with its two-pane view of the file system. MFC has a complex and powerful splitter window class, however it is somewhat difficult to learn how to use, and coupled to the doc/view framework. In Part VII, I will discuss the WTL splitter window, which is much less complicated than MFC's. While WTL's splitter implementation does have fewer features than MFC's, it is far easier to use and extend.

The sample project for this part will be a rewrite of ClipSpy, using WTL of course instead of MFC. If you're not familiar with that program, please check out the article now, as I will be duplicating the functionality of ClipSpy here without providing in-depth explanations of how it works. This article's focus is the splitter window, not the clipboard.

The header file atlsplit.h contains all of the WTL splitter window classes. There are three classes: CSplitterImpl, CSplitterWindowImpl, and CSplitterWindowT. The classes and their basic methods are explained below.

CSplitterImpl is a template class that takes two template parameters, a window interface class name and a boolean that indicates the splitter orientation: true for vertical, false for horizontal. CSplitterImpl has almost all of the implementation for a splitter, and many methods are overridable so you can provide custom drawing of the split bar or other effects. CSplitterWindowImpl derives from CWindowImpl and CSplitterImpl, but doesn't have much code. It has an empty WM_ERASEBKGND handler, and a WM_SIZE handler that resizes the splitter window.

Finally, CSplitterWindowT derives from CSplitterImpl and provides a window class name. If you don't need to do any customization, there are two convenient typedefs that you can use: CSplitterWindow for a vertical splitter, and CHorSplitterWindow for a horizontal splitter.

Since CSplitterWindow derives from CWindowImpl, you create a splitter just like any other child window. When a splitter will exist for the lifetime of the main frame, as it will in ClipSpy, you can add a CSplitterWindow member variable to CMainFrame. In CMainFrame::OnCreate(), you create the splitter as a child of the frame, then set the splitter as the main frame's client window:

Call SetSplitterPos() to set the position of the splitter bar. The position is expressed in pixels relative to the top edge (for horizontal splitters) or left edge (for vertical splitters) of the splitter window. You can use the default of -1 to position the splitter bar in the middle, making both panes the same size. You will usually pass true for bUpdate, to have the splitter immediately resize the panes accordingly. GetSplitterPos() returns the current position of the splitter bar, relative to the top or left edge of the splitter window. (If the splitter is in single-pane mode, GetSplitterPos() returns the position the bar will return to when both panes are shown.)

Call SetSinglePaneMode() to change the splitter between one-pane and two-pane mode. In one-pane mode, only one pane is visible and the splitter bar is hidden, similar to how MFC dynamic splitters work (although there is no little gripper handle to re-split the splitter). The allowable values for nPane are: SPLIT_PANE_LEFT, SPLIT_PANE_RIGHT, SPLIT_PANE_TOP, SPLIT_PANE_BOTTOM, and SPLIT_PANE_NONE. The first four indicate which pane to show (for example, passing SPLIT_PANE_LEFT shows the left-side pane and hides the right-side pane). Passing SPLIT_PANE_NONE shows both panes. GetSinglePaneMode() returns one of those five SPLIT_PANE_* values indicating the current mode.

If none of those three styles are specified, the splitter defaults to being left- or top-aligned. If you pass SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED/SPLIT_BOTTOMALIGNED together, SPLIT_PROPORTIONAL takes precedence.

Call SetSplitterPane() to assign a child window to one pane of the splitter. nPane is one of the SPLIT_PANE_* values indicating which pane you are setting. hWnd is the window handle of the child window. You can assign child windows to both panes at once with SetSplitterPanes(). You will usually use the default value of bUpdate, which tells the splitter to immediately resize the child windows to fit in the panes. SetSplitterPane() returns a bool, however it will only return false if you pass an invalid value for nPane.

SetActivePane() sets the focus to one of the windows in the splitter. nPane is one of the SPLIT_PANE_* values indicating which pane you are setting as the active one. It also sets the default active pane (explained below). GetActivePane() checks the window with the focus, and if that window is a pane window or a child of a pane window, returns a SPLIT_PANE_* value indicating which pane. If the window with the focus is not a child of a pane, GetActivePane() returns SPLIT_PANE_NONE.

If the splitter is in single-pane mode, the focus is set to the visible pane. Otherwise, ActivateNextPane() checks the window with the focus using GetActivePane(). If a pane (or child of a pane) has the focus, the splitter sets the focus to the other pane. Otherwise, ActivateNextPane() activates the left/top pane if bNext is true, or the right/bottom pane if bNext is false.

Call SetDefaultActivePane() with either a SPLIT_PANE_* value or window handle to set that pane as the default active pane. If the splitter window itself gets the focus, via a SetFocus() call, it in turn sets the focus to the default active pane. GetDefaultActivePane() returns a SPLIT_PANE_* value indicating the current default active pane.

The splitter calls this method when it is created, so you don't have to call it yourself. However, your main frame should handle the WM_SETTINGCHANGE message and pass it along to the splitter; CSplitterWindow calls GetSystemSettings() in its WM_SETTINGCHANGE handler.

Now that we have the basics out of the way, let's see how to set up a frame window that contains a splitter. Start a new project with the WTL AppWizard. On the first page, leave SDI Application selected and click Next. On the second page, uncheck Toolbar, then uncheck Use a view window as shown here:

Note that you need to set m_hWndClient and call CFrameWindowImpl::UpdateLayout() before setting the splitter position. UpdateLayout() resizes the splitter window to its initial size. If you skip that step, the splitter's size isn't under your control and it might be smaller than 200 pixels wide. The end result would be that SetSplitterPos() wouldn't have the effect you wanted.

An alternative to calling UpdateLayout() is to get the client RECT of the frame window, and use that RECT when creating the splitter, instead of rcDefault. This way, you create the splitter in its initial position, and all subsequent methods dealing with position (like SetSplitterPos()) will work correctly.

If you run the app now, you'll see the splitter in action. Even without creating anything for the panes, the basic behavior is there. You can drag the bar, and double-clicking it moves the bar to the center.

To demonstrate different ways of managing the pane windows, I'll use one CListViewCtrl-derived class, and a plain CRichEditCtrl. Here's a snippet from the CClipSpyListCtrl class, which we'll use in the left pane:

Now that we have member variables for the splitter and the panes, filling in the splitter is a simple matter. After creating the splitter window, we create both child windows, using the splitter as their parent:

Notice that both Create() calls use m_wndVertSplit as the parent window. The RECT parameter is not important, since the splitter will resize both pane windows as necessary, so we can use CWindow::rcDefault.

Note that the splitter puts no restrictions on what windows can go in the panes, unlike MFC where you are supposed to use CViews. The pane windows should have at least the WS_CHILD style, but beyond that you're pretty much free to use anything.

A little sidebar is in order about the effect that the WS_EX_CLIENTEDGE style has on the splitter and the windows in the panes. There are three places where we can apply this style: the main frame, the splitter window, or the window in a splitter pane. WS_EX_CLIENTEDGE creates a different look in each case, so I will illustrate them here.

Since we now have another window sitting between the main frame and the pane windows, you might have wondered how notification messages work. Specifically, how can the main frame receive NM_CUSTOMDRAW notifications so it can reflect them to the list? The answer can be found in the CSplitterWindowImpl message map:

The FORWARD_NOTIFICATIONS() macro at the end is the important one. Recall from Part IV that there are several notification messages which are always sent to the parent of a child window. What FORWARD_NOTIFICATIONS() does is re-send the message to the splitter's parent window. So when the list sends a WM_NOTIFY message to the splitter (the list's parent), the splitter in turn sends the WM_NOTIFY to the main frame (the splitter's parent). When the main frame reflects the message, it is sent back to the window that generated the WM_NOTIFY in the first place, so the splitter doesn't get involved in reflection.

The result of all this is that notification messages sent between the main frame and the list don't get affected by the presence of the splitter window. This makes it rather easy to add or remove splitters, because the child window classes won't have to be changed at all for their message processing to continue working.

Creating a CPaneContainer is similar to creating other child windows. There are two Create() methods that differ in just the second parameter. In the first version, you pass a string that will be used for the title text drawn in the header. In the second method, you pass the ID of a string table entry. The defaults for the remaining parameters are usually sufficient.

f5d0e4f075
Reply all
Reply to author
Forward
0 new messages