views provides support for creating dialog boxes and other kinds of windows through its Window object. The developer creates a WindowDelegate (or sub-interface) implementation that provides the Window with the necessary information to display itself, and also provides callbacks for notifications about windowing events.A Simple Example
To create a simple window:
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/views/label.h"
#include "chrome/views/view.h"
#include "chrome/views/window.h"
#include "chrome/views/window_delegate.h"
class WindowView : public views::View, public views::WindowDelegate {
public:
WindowView() : label_(new views::Label(L"Hello, World!")) {
AddChildView(label_);
}
// Overridden from views::View:
virtual void Paint(ChromeCanvas* canvas) {
canvas->FillRectInt(SK_ColorWHITE, 0, 0, width(), height());
}
virtual void Layout() {
gfx::Size ps = label_->GetPreferredSize();
label_->SetBounds((width() - ps.width() )/ 2, (height() - ps.height()) / 2, ps.width(), ps.height());
}
virtual gfx::Size GetPreferredSize() {
gfx::Size ps = label_->GetPreferredSize();
ps.set_width(ps.width() + 200);
ps.set_height(ps.height() + 200);
return ps;
}
// Overridden from views::WindowDelegate:
virtual std::wstring GetWindowTitle() const {
return L"Hello World Window";
}
virtual bool CanResize() const {
return true;
}
virtual bool CanMaximize() const {
return true;
}
virtual views::View* GetContentsView() {
return this;
}
private:
views::Label* label_;
DISALLOW_COPY_AND_ASSIGN(WindowView);
};
...
views::Window::CreateChromeWindow(NULL, gfx::Rect(), new WindowView)->Show();
The window will delete itself when the user closes it, which will cause the RootView within it to be destroyed, including the WindowView.
WindowDelegate
The WindowDelegate is an interface that provides information to the Window class used when displaying the window, such as its title and icon, as well as properties such as whether or not the Window can be resized. It also provides callbacks for events like closing. It has an accessor window() which provides access to the associated Window object. A Window has a ContentsView, provided by the WindowDelegate, which is a View that is inserted into theWindow's client area.
DialogDelegate
A DialogDelegate is a specialized kind of WindowDelegate specific to dialog boxes that have OK/Cancel buttons. The DialogDelegate and its associated ClientView (see below) provide built in OK/Cancel buttons, keyboard handlers for Esc/Enter and enabling for those features. As a user, you write a View that is inserted into the DialogClientView that provides the contents of the dialog box, and implement DialogDelegate instead ofWindowDelegate, which provides callbacks for when the buttons are clicked as well as methods to provide the button text, etc.
Client and Non Client Views
Due to Chrome's non-standard window design, views supports custom rendered non-client areas. This is supported via the Window class andNonClientFrameView subclasses. To provide a custom window frame, a View subclasses NonClientFrameView. This allows the overriding View to render and respond to events from the non-client areas of a window. views contains two built in type that do this - CustomFrameView and NativeFrameView. These are used for standard dialog boxes and top level windows.
For the
Browser Window, different subclasses of
NonClientFrameView are used (
GlassBrowserFrameView and
OpaqueBrowserFrameView). To allow these to be used the browser overrides Window's CreateFrameViewForWindow method to construct the appropriate frame view.
Aside from the RootView, the topmost View in a Window's View hierarchy is the NonClientView. This view is a container of exactly two views - theNonClientFrameView described above and a ClientView or subclass. The ClientView subclass contains the contents of the client area of the window (the stuff inside the titlebar/frame). A common ClientView subclass is DialogClientView, which provides built in handling for OK/Cancel buttons and a dialog theme background. The specific ClientView to be used is specified by a WindowDelegate in its CreateClientView implementation. The default implementation of DialogDelegate automatically creates a DialogClientView. Custom WindowDelegates can implement this method to return their own ClientView, which is what BrowserView does (the Browser window's WindowDelegate implementor) to return itself. The ClientView API is fairly minimal except it is given a chance to perform non-client hit-testing, which is how the draggable title bar within the TabStrip and the resize corner of windows is implemented.
The ClientView and NonClientFrameView are siblings because it is fairly common for Views to do one-time initialization when they are inserted into a View hierarchy and DWM toggling on Windows Vista and newer mean the NonClientFrameView needs to be swapped out when the DWM is enabled or disabled. As such if the ClientView were a child of the NonClientFrameView it would be re-parented, meaning its children might re-initialize with negative side-effects.
Creating a Window
Some simple code to create a Window using the WindowView defined in the example above:
views::Window* window = views::Window::CreateChromeWindow(NULL, new WindowView);
window->Show();
评论