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

📄 generic.html.primary

📁 很好的,电子书籍,我找了好久的
💻 PRIMARY
📖 第 1 页 / 共 3 页
字号:
<hr>
class <font color="#cc0066"><b>TopWinClass</b></font>: public <font color="#cc0066"><b>WinClass</b></font>
{
public:
    TopWinClass (int resId, HINSTANCE hInst, WNDPROC wndProc);
};

<font color="#cc0066"><b>TopWinClass::TopWinClass</b></font> (int resId, 
           HINSTANCE hInst, WNDPROC wndProc)
    : WinClass (resId, hInst, wndProc)
{
    SetResIcons (resId);
    _class.lpszMenuName = MAKEINTRESOURCE (resId);
}</font></pre><!--End Code-->
                       <td width=20>
        </table>
        <!--End of yellow background-->


<hr><!--Text-->
Once the Windows class is registered with the system, you can create as many windows of this class as you wish. They will, of course, share the same Window procedure that was registered with the class. We'll see later how we can distinguish between various instances of the window inside the procedure.
<p>The class <font color="#cc0066"><b>WinMaker</b></font> works in much the same way as <font color="#cc0066"><b>WinClass</b></font>. Its constructor provides sensible defaults that may be overriden by calling particular methods. Once everything is set, you call the <font color="#cc0066"><b>Create</b></font> method to create the window and the <font color="#cc0066"><b>Show</b></font> method to display it. Notice that the moment you call Create, your Window procedure is called with the <font color="#009966">WM_CREATE</font> message.
<p>The top window is created using TopWinMaker class, which provides the appropriate style and caption.

<hr><!--End Text-->

         <!--Yellow background-->
        <table cellpadding=10 cellspacing=0 width="100%">
                <tr>
                      <td width=20>
            	      <td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->
class <font color="#cc0066"><b>WinMaker</b></font>
{
public:
    WinMaker (WinClass & winClass);
    operator HWND () { return _hwnd; }
    void AddCaption (char const * caption)
    {
        _windowName = caption;
    }
    void AddSysMenu ()    { _style |= WS_SYSMENU; }
    void AddVScrollBar () { _style |= WS_VSCROLL; }
    void AddHScrollBar () { _style |= WS_HSCROLL; }
    void Create ();
    void Show (int nCmdShow = SW_SHOWNORMAL);
protected:
    WinClass   & _class;
    HWND         _hwnd;

    DWORD        _exStyle;       // extended window style
    char const * _windowName;    // pointer to window name
    DWORD        _style;         // window style
    int          _x;             // horizontal position of window
    int          _y;             // vertical position of window
    int          _width;         // window width  
    int          _height;        // window height
    HWND         _hWndParent;    // handle to parent or owner window
    HMENU        _hMenu;         // handle to menu, or child-window identifier
    void       * _data;          // pointer to window-creation data
};

<font color="#cc0066"><b>WinMaker::WinMaker</b></font> (WinClass & winClass)
  : _hwnd (0),
    _class (winClass),
    _exStyle (0),       // extended window style
    _windowName (0),    // pointer to window name
    _style (WS_OVERLAPPED), // window style
    _x (CW_USEDEFAULT), // horizontal position of window
    _y (0),             // vertical position of window
    _width (CW_USEDEFAULT), // window width  
    _height (0),        // window height
    _hWndParent (0),    // handle to parent or owner window
    _hMenu (0),         // handle to menu, or child-window identifier
    _data (0)           // pointer to window-creation data
{
}

void <font color="#cc0066"><b>WinMaker::Create</b></font> ()
{
    _hwnd = ::<font color="#000099"><b>CreateWindowEx</b></font> (
        _exStyle,
        _class.GetName (),
        _windowName,
        _style,
        _x,
        _y,
        _width,
        _height,
        _hWndParent,
        _hMenu,
        _class.GetInstance (),
        _data);

    if (_hwnd == 0)
        throw WinException ("Internal error: Window Creation Failed.");
}

void <font color="#cc0066"><b>WinMaker::Show</b></font> (int nCmdShow)
{
    ::ShowWindow (_hwnd, nCmdShow);
    ::UpdateWindow (_hwnd);
}

// Makes top overlapped window with caption

<font color="#cc0066"><b>TopWinMaker::TopWinMaker</b></font> ((WinClass & winClass, char const * caption)
    : WinMaker (winClass)
{
    _style = <font color="#009966">WS_OVERLAPPEDWINDOW</font> | <font color="#009966">WS_VISIBLE</font>;
    _windowName = caption;
}

</font></pre><!--End Code-->
                       <td width=20>
        </table>
        <!--End of yellow background-->
<hr><!--Text-->

Before we go any further, here are some light-weight classes of general interest. <font color="#cc0066"><b>WinException</b></font> is something that we want to throw any time a Windows API fails. It takes care of retrieving the Windows error code. (By the way, there is an easy way to convert the error code to a string using <font color="#000099"><b>FormatMessage</b></font> API.) 
<p>The class <font color="#cc0066"><b>ResString</b></font> is a simple encapsulation of a string stored in the string resources of your application.

<hr><!--End Text-->

         <!--Yellow background-->
        <table cellpadding=10 cellspacing=0 width="100%">
                <tr>
                      <td width=20>
                      <td bgcolor="#e0e080">
<pre><font face="courier">
<font color="#cc0066">// The exception class: stores the message and the error code</font>
class <font color="#cc0066"><b>WinException</b></font>
{
public:
    WinException (char* msg)
    : _err (::<font color="#000099"><b>GetLastError</b></font>()), _msg(msg)
    {}
    DWORD GetError() const { return _err; }
    char const * GetMessage () const { return _msg; }
private:
    DWORD  _err;
    char * _msg;
};

<font color="#cc0066">// The out-of-memory handler: throws exception</font>
int <font color="#cc0066"><b>NewHandler</b></font> (size_t size)
{
    throw WinException ( "Out of memory" );
    return 0;
}

class <font color="#cc0066"><b>ResString</b></font>
{
    enum { MAX_RESSTRING = 255 };
public:
    ResString (HINSTANCE hInst, int resId);
    operator char const * () { return _buf; }
private:
    char _buf [MAX_RESSTRING + 1];
};

<font color="#cc0066"><b>ResString::ResString</b></font> (HINSTANCE hInst, int resId)
{
    if (!::<font color="#000099"><b>LoadString</b></font> (hInst, resId, _buf, MAX_RESSTRING + 1))
        throw WinException ("Load String failed");
}</font></pre>

<!--End Code-->
                      <td width=20>
        </table>
        <!--End of yellow background-->
<hr><!--Text-->
The <b>Controller</b> is the nervous system of a particular <i>window instance</i>. It is created with that window, stored with it and finally destroyed with it. You can put any state information pertaining to a particular window instance in its controller. In general, the controller has a <i>view</i> that deals with painting on the window's surface and it has access to the <i>model</i>, which is the brain of your application (this is called the MVC, or Model-View-Controller pattern invented by Smalltalk programmers). 
<p>If, as it often happens, your application has only one top-level window, you can directly embed the <i>model</i> in its controller. That simplifies the management of resources but at the cost of tight coupling of the controller with the model. In large projects one should avoid such couplings--the use of a (smart) pointer to the model inside the controller is then preferred.
<p>Most controller methods require a handle to the window on which behalf they are operating. This handle is passed with every Windows message, but it is simpler to store it once inside the controller object and use it whenever necessary. Remember--there is a one-to-one correspondence between window instances (and therefore window handles) and <i>controller</i> objects.
<hr><!--End Text-->

         <!--Yellow background-->
        <table cellpadding=10 cellspacing=0 width="100%">
                <tr>
                      <td width=20>
                      <td bgcolor="#e0e080">
<pre><font face="courier">
class <font color="#cc0066"><b>Controller</b></font>
{
public:
    Controller(HWND hwnd, CREATESTRUCT * pCreate);
    ~Controller ();
    void    Size (int x, int y);
    void    Paint ();
    void    Command (int cmd);

private:

    HWND        _hwnd;

    Model       _model;
    View        _view;
};</font></pre><!--End Code-->
                      <td width=20>
        </table>
        <!--End of yellow background-->
<hr><!--Text-->
The <b>Window Procedure</b> is the main switchboard of a Windows application. You don't call it from your program--Windows calls it! Every time something interesting happens, Windows sends your program a message. This message is passed to your window procedure. You may deal with it, or you may pass it on to the <i>default window procedure</i>.

<p>Window procedure is called with a handle to a window to which a given message is directed. This handle uniquely identifies an internal Windows' data structure that corresponds to a given window instance. It so happens that we can access this data structure and use it to store some instance-specific data. Here's the type safe way of accessing this structure. By the way, the <font color="#009966">GWL_USERDATA</font> member of this structure is guaranteed to be present in all windows, including message boxes, dialog boxes and even buttons.
<hr><!--End Text-->
         <!--Yellow background-->
        <table cellpadding=10 cellspacing=0 width="100%">
                <tr>
                      <td width=20>
                      <td bgcolor="#e0e080">
<pre><font face="courier"><!--Code-->
template &lt;class T&gt;
inline T <font color="#cc0066"><b>WinGetLong</b></font> (HWND hwnd, int which = <font color="#009966">GWL_USERDATA</font>)
{
    return reinterpret_cast&lt;T&gt; (::<font color="#000099"><b>GetWindowLong</b></font> (hwnd, which));
}

template &lt;class T&gt;
inline void <font color="#cc0066"><b>WinSetLong</b></font> (HWND hwnd, T value, int which = <font color="#009966">GWL_USERDATA</font>)
{
    ::<font color="#000099"><b>SetWindowLong</b></font> (hwnd, which, reinterpret_cast&lt;long&gt; (value));
}
</font></pre><!--End Code-->
                       <td width=20>
        </table>
        <!--End of yellow background-->
<hr><!--Text-->
Every time Windows calls our window procedure, we want to first retrieve its controller object. Remember, there may be several windows sharing the same window procedure and we want to have a separate controller for each window. How do we know which controller to use when we are called? We find out by looking at the window handle. In this handle we store the pointer to this particular window's controller using the Win[Set/Get]Long trick.

<p>The Window procedure is first called with the <font color="#009966">WM_CREATE</font> message. At that time we <b>create the controller</b> object and initialize it with the window handle and a special data structure called <font color="#009966">CREATESTRUCT</font> that is passed to us by Windows. Once we have the controller, we store the pointer to it in the corresponding internal Windows' data structure under the label of the current <b>hwnd</b>. Next time the Window procedure is called, with a message other than <font color="#009966">WM_CREATE</font>, we simply retrieve the pointer to our controller using the <b>hwnd</b>.
<p>The rest is easy. The Window procedure interprets message parameters and calls the appropriate methods of the controller.
<hr><!--End Text-->
         <!--Yellow background-->
        <table cellpadding=10 cellspacing=0 width="100%">
                <tr>
                      <td width=20>
                      <td bgcolor="#e0e080">
<pre><font face="courier">
LRESULT CALLBACK <font color="#cc0066"><b>WndProc</b></font>
    (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    Controller * pCtrl = WinGetLong&lt;Controller *&gt; (hwnd);

    switch (message)
    {
    case WM_CREATE:
        <font color="#cc0066">// Have to catch exception in case new throws!</font>
        try

⌨️ 快捷键说明

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