// exception类:贮存消息和错误代码
class WinException
{
public:
WinException (char* msg)
: _err (::GetLastError()), _msg(msg)
{}
DWORD GetError() const { return _err; }
char const * GetMessage () const { return _msg; }
private:
DWORD _err;
char * _msg;
};
// 内存溢出:抛出异常
int NewHandler (size_t size)
{
throw WinException ( "Out of memory" );
return 0;
}
class ResString
{
enum { MAX_RESSTRING = 255 };
public:
ResString (HINSTANCE hInst, int resId);
operator char const * () { return _buf; }
private:
char _buf [MAX_RESSTRING + 1];
};
ResString::ResString (HINSTANCE hInst, int resId)
{
if (!::LoadString (hInst, resId, _buf, MAX_RESSTRING + 1))
throw WinException ("Load String failed");
}
--------------------------------------------------------------------------------
Controller是一个特别的窗口实例的强健的系统。它建立了窗口,贮存了它,并在最后销毁了它。在它的控制内你可以放置一些对特定窗口实例的描述信息。在通常,控件器有一个视(通过在窗口的表面绘制进行交互)并且它有权使用model。它相当于你的应用程序的大脑(在这,MVC或Model-View-Controller通过Smalltalk程序师被调用)。
如果,这常常发生,你的应用程序只有一个最顶层的窗口,你可以在它的控制中立即插入model。这单一化的资源管理,这是以控件器与model的紧密联系的。在大的项目中应该避免这样的联接——首选在控制器里使用一个指向model的指针。
更多的controller方法为了它们操作的利益需要一个指向窗口的句柄。这个句柄是每一个窗口消息通过的句柄,但它只是一次性的简单的贮存它到controller对象里,随时都可以使用它。记住——在窗口实例(因为窗口的句柄)和controller对象之间有一对一的通信。
--------------------------------------------------------------------------------
class Controller
{
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;
};
--------------------------------------------------------------------------------
窗口过程是一个窗口应用程序的主交换器。你不能在你的程序窗口中调用它!每当某件有意义的事件发生,Windows发送条消息给你的程序。这条消息被你的窗口过程传递。你可以处理它,或传递它到默认的窗口过程。
窗口过程被给定消息指定的窗口调用的。这个句柄是独一无二的一个协调窗口实例的内部窗口数据。它发生时,我们可以访问这些数据结构,及使用它去贮存一些实例指定的数据。这是典型的安全的访问结构的途径。顺便,这个结构的GWL_USERDATA成员是所有窗口允许给出的。包含消息框,对话框及平滑按钮。
--------------------------------------------------------------------------------
template <class T>
inline T WinGetLong (HWND hwnd, int which = GWL_USERDATA)
{
return reinterpret_cast<T> (::GetWindowLong (hwnd, which));
}
template <class T>
inline void WinSetLong (HWND hwnd, T value, int which = GWL_USERDATA)
{
::SetWindowLong (hwnd, which, reinterpret_cast<long> (value));
}
--------------------------------------------------------------------------------
每当Windows调用我们的窗口过程时,我们应该首先找回它的控制对象。记住,在这可能几个窗口共享相同的窗口过程,我们应该为每个窗口分别控制。当我们被调用后怎么样知道去使用哪个控制?我们通过找出窗口的句柄。在这个句柄里我们贮存了指向这个特定窗口的控制器,使用Win[Set/Get]Long技巧。
窗口过程首先被WM_CREATE消息调用。在那时我们建立了控制器对象并初始化了带有窗口句柄的它,且通过调用CREATESTRUCT指定了数据结构。一旦我们有了控制器,我们贮存指向在当前hwnd的标签下相应的内部窗口的数据结构。在下次窗口过程被调用,带有一个不同与WM_CREATE的消息,我们只要简单的取回指向我们控制器的指针,使用hwnd。
这个支持是容易的。窗口过程解释消息参数及调用控制器的适当模块。
--------------------------------------------------------------------------------
上一页 [1] [2] [3] [4] [5] [6] 下一页