popcap sexyframework - 该库在1.2版的变化 详见main.cpp

//board.h

#ifndef __BOARD_H__
#define __BOARD_H__

#include "..\SexyAppFramework\Widget.h"
#include "..\SexyAppFramework\ButtonListener.h"
#include "..\SexyAppFramework\Rect.h"

namespace Sexy
{

class V12DemoApp;
class DemoWidget;
class ButtonWidget;

class Board : public Widget, public ButtonListener
{

public:

 V12DemoApp* mApp;

private:

 // 我们将使用门帘效果. 用下边几个常量表示门帘的几种状态.
 enum
 {
  CURTAIN_CLOSING,
  CURTAIN_OPENING,
  CURTAIN_INACTIVE
 };

 DemoWidget*  mDemoWidget;  
 ButtonWidget* mDemoButton;  // Creates our DemoWidget
 ButtonWidget* mDialogButton;  // Creates a little dialog box
 ButtonWidget* mCurtainButton;  // Initiates the curtain closing/opening transition

 Rect   mRect;    // 不断变化大小的矩形 
 bool   mExpanding;   // 矩形在放大还是缩小?

 bool   mLostFocus;   // 程序是否失去了焦点?  在本例子中失去焦点后程序做另一些事情.
 
 int    mCurtainMode;  // 前边定义的enum中的某一个状态.

 int    mCurtainWidth;  // 记录门帘的宽. 其变化范围在 0 到 宽/2 .

 int    mDeferPriority;  // See the .cpp for full info, but we'll be toggling the overlay priority every second

 int    mMsgX, mMsgY;  // 每秒都移动一下 "LOST FOCUS" 文字. (当窗口失去焦点时. 该文字才显示出来).

public:

 Board(V12DemoApp* theApp);
 virtual ~Board();

 void  Update();
 void  Draw(Graphics* g);
 void  ButtonDepress(int id);

 //
 // 在最上层绘制. 它将把图像绘制在所有的控件之上.
 // 无论何时你需要这种绘制. 你只需在 Draw() 中调用 DeferOverlay() 函数就可以了 . 
 //  调用 DeferOverlay()时可以指定一个优先级. 优先级越高就越显示到最上层.
 //  可以通过设置优先级来使这种顶层绘制遮住一部分部件. 而不会遮住优先级更高的部件(例如一个设置对话框).
 void  DrawOverlay(Graphics* g);
 

 void  SetFocusLost(bool f) {mLostFocus = f; mDeferPriority = 2;}
};

}

#endif //__BOARD_H__

//demowiget.h

#ifndef __DEMO_WIDGET_H__
#define __DEMO_WIDGET_H__

#include "SexyAppFramework/Widget.h"
#include "SexyAppFramework/ButtonListener.h"

namespace Sexy
{

 class ButtonWidget;
 

 class DemoWidget : public Widget, public ButtonListener
 {

 private:

  ButtonWidget* mMoveButton;
  ButtonWidget* mCloseButton;

 public:

  DemoWidget();
  virtual ~DemoWidget();

  void  Draw(Graphics* g);
  void  ButtonDepress(int id);
 };

}

#endif //__DEMO_WIDGET_H__

// v12Demo.h

#ifndef __V12DEMOAPP_H__
#define __V12DEMOAPP_H__

#include "..\SexyAppFramework\SexyAppBase.h"

namespace Sexy
{

class Board;

class V12DemoApp : public SexyAppBase
{

public:

 Board*     mBoard;

public:

 V12DemoApp();
 virtual ~V12DemoApp();

 //
 // Function: ShutdownHook
 // 它被基类的 Shutdown() 函数自动调用. 所以这里可以放一些需要在程序关闭时执行的动作. 如释放资源等等.
 virtual void ShutdownHook();
 
 // 
 // 不再需要重载基类的 Init() 函数. 而应该把一些需要初始化时做的工作放在这里(例如载入资源).
 // 它会在调用基类的 Init() 函数时被自动执行.  
 virtual void InitHook();
 
 // 这两个函数可以使程序在获得焦点/失去焦点时做些事情.  
 virtual void LostFocus();
 virtual void GotFocus();
 
 // 
 // 以前的例子中. 对话框的按钮的"按下/弹起"事件总是发送到 ButtonListener. 处理起来比较麻烦.
 // 现在 则只要在 app 类的 DialogButtonDepress / DialogButtonPress 函数中检查
 // 指定的 对话框ID 和 按钮ID. 然后指定一个动作执行之.
 virtual void DialogButtonDepress(int dialog_id, int button_id);
};

}
#endif //__V12DEMOAPP_H__

//board.cpp

#include "Board.h"
#include "DemoWidget.h"
#include "Res.h"
#include "V12DemoApp.h"
#include "..\SexyAppFramework\Font.h"
#include "..\SexyAppFramework\Graphics.h"
#include "..\SexyAppFramework\ButtonWidget.h"
#include "..\SexyAppFramework\WidgetManager.h"
#include "..\SexyAppFramework\Dialog.h"
#include "..\SexyAppFramework\Flags.h"
#include "..\SexyAppFramework\SexyMatrix.h"
#include "..\SexyAppFramework\trivertex.h"

using namespace Sexy;

Board::Board(V12DemoApp* theApp)
{
 mApp = theApp;


 // 这里演示如何用部件的 flag system 来设置部件的一些特征. 如是否总是在每帧都重绘. 是否允许鼠标事件等等...
 // 它通过设置一些 flag 来指定 widget 这些特征. widget缺省被设置的旗标有:
 //  WIDGETFLAGS_UPDATE  - 允许调用其 Update() 函数.
 //  WIDGETFLAGS_DRAW  - 允许调用其 Draw() 函数.
 //  WIDGETFLAGS_CLIP  - 绘制的图像都剪裁到部件的区域之内(不能在区域之外绘制).
 //  WIDGETFLAGS_ALLOW_MOUSE - 允许鼠标操作.
 //  WIDGETFLAGS_ALLOW_FOCUS - 允许处理焦点事件.

 // 以前. 为了让部件在每次 Update() 时都绘制一次. 我们在Update()中调用 MarkDirty().
 // 现在有另一个办法. 即使用窗体部件的 flag system.  例如下边的例子中. 我们设置 WIDGETFLAGS_MARK_DIRTY 旗标.
 // 这样当我们将该 widget 放入部件管理器时. 部件管理器就知道我们想要它在每帧都重画. 
 mWidgetFlagsMod.mAddFlags |= WIDGETFLAGS_MARK_DIRTY;
 // 如上例所示. 要设置一个旗标用 "mWidgetFlagsMod.mAddFlags |= 标志" .
 // 而要取消某个旗标则用 "mWidgetFlagsMod.mRemoveFlags |= 标志" 的形式.

 // 你也可以修改所有部件的缺省特征.  这需要修改 mApp->mWidgetManager 的 mWidgetFlags.


 // 以前, 要把一个 widget 做为子窗口插入另一个 widget 是很烦人的. 
 // 所以以前的例子中你必须重写 AddedToManager/RemovedFromManager 函数....等等...
 // 现在可以直接在父部件的构造函数中创建子部件. 可以用成员函数 AddWidget() 将子部件插入. 
 // 而且. 在父部件的析够函数中. 也只要在 delete 子部件前加上一句 RemoveAllWidgets() 就可以方便的从部件管理器中移除所有子部件了. 

 // 创建3个按钮子部件. 
 mDemoButton = new ButtonWidget(0, this);
 mDemoButton->mLabel = _S("Demo Widget");
 mDemoButton->SetFont(FONT_DEFAULT);
 mDemoButton->Resize(10, 10, 10 + FONT_DEFAULT->StringWidth(mDemoButton->mLabel), 50);
 AddWidget(mDemoButton);

 mDialogButton = new ButtonWidget(1, this);
 mDialogButton->mLabel = _S("Do Dialog");
 mDialogButton->SetFont(FONT_DEFAULT);
 int w = FONT_DEFAULT->StringWidth(mDialogButton->mLabel);
 mDialogButton->Resize(mApp->mWidth - 20 - w, 10, w + 10, 50);
 AddWidget(mDialogButton);

 mCurtainButton = new ButtonWidget(2, this);
 mCurtainButton->mLabel = _S("Do Transition");
 mCurtainButton->SetFont(FONT_DEFAULT);
 w = FONT_DEFAULT->StringWidth(mCurtainButton->mLabel);
 mCurtainButton->Resize(mDemoButton->mX + 20 + mDemoButton->mWidth, 10, w + 10, 50);
 AddWidget(mCurtainButton);

 

 mDemoWidget = NULL;
 
 mRect = Rect(mApp->mWidth / 2 - 1, mApp->mHeight / 2 - 1, 2, 2);
 mExpanding = true;

 mMsgX = Rand() % (mApp->mWidth - 100);
 mMsgY = Rand() % (mApp->mHeight - 100);

 mLostFocus = false;

 mCurtainWidth = 0;
 mCurtainMode = CURTAIN_INACTIVE;

 // We'll toggle this between 0 and 2 every second when we are unfocussed
 mDeferPriority = 0;
}

Board::~Board()
{
 // 必须在delete子部件之前调用如下函数. 它可以移除所有子部件. 
 // 它会将所有的子部件从部件管理器中移除.
 RemoveAllWidgets();

 delete mDemoButton;
 delete mDialogButton;
 delete mCurtainButton;

 // mDemoWidget 它没有被设置为Board的子部件. 所以上边的 RemoveAllWidgets() 没有移除它. 
 // 所以需要手动移除.
 if (mDemoWidget != NULL)
  mApp->mWidgetManager->RemoveWidget(mDemoWidget);

 delete mDemoWidget;
}

void Board::Update()
{
 Widget::Update();

 if (mLostFocus)
 {
  if (mUpdateCnt % 100 == 0)
  {
   mMsgX = Rand() % (mApp->mWidth - 100);
   mMsgY = Rand() % (mApp->mHeight - 100);

   // Every second, we switch between drawing the overlay above or below
   // the mDemoWidget object (assuming of course you have the widget on screen
   // when you lose focus).
   mDeferPriority = mDeferPriority == 0 ? 2 : 0;
  }
 }
 else
 {  
  // This just makes the rectangle in the middle grow/shrink. Nothing
  // too crazy.
  if (mExpanding)
  {
   mRect.mWidth += 2;
   mRect.mHeight += 2;

   if (mRect.mWidth >= mApp->mWidth)
   {
    mRect.mWidth = mApp->mWidth;
    mExpanding = false;
   }

   if (mRect.mHeight >= mApp->mHeight)
   {
    mRect.mHeight = mApp->mHeight;
    mExpanding = false;
   }
  }
  else
  {
   mRect.mWidth -= 2;
   mRect.mHeight -= 2;

   if (mRect.mHeight <= 0)
   {
    mRect.mHeight = 0;
    mExpanding = true;
   }

   if (mRect.mWidth <= 0)
   {
    mRect.mWidth = 0;
    mExpanding = true;
   }

  }

  mRect.mX = mApp->mWidth / 2 - mRect.mWidth / 2;
  mRect.mY = mApp->mHeight / 2 - mRect.mHeight / 2;
 }
}

void Board::Draw(Graphics* g)
{
 g->SetColor(Color::Black);
 g->FillRect(0, 0, mWidth, mHeight);

 // Draw our pulsing rectangle in the middle of the screen.
 g->SetColor(Color(255, 0, 0));
 g->FillRect(mRect);

 if (!mLostFocus)
 {
  // GraphicsAutoState 对象的用法就像 互斥器中的"守卫". 
  // 它的构造函数执行 g->PushState() 而析够函数执行 g->PopState() . 
  GraphicsAutoState auto_state(g);
  g->DrawImage(IMAGE_HUNGARR_LOGO, 10, 100);
  g->SetDrawMode(Graphics::DRAWMODE_ADDITIVE);
  g->SetColorizeImages(true);
  g->SetColor(Color(mUpdateCnt % 128, mUpdateCnt % 255, mUpdateCnt % 64));
  g->DrawImage(IMAGE_HUNGARR_LOGO, 10, 100);
 }

 if (mCurtainMode != CURTAIN_INACTIVE)
 {
  g->SetColor(Color(255, 255, 0));
  g->FillRect(0, 0, mCurtainWidth, mHeight);
  g->FillRect(mWidth - mCurtainWidth, 0, mCurtainWidth, mHeight);
 }

 // 本例子中. 当失去焦点的时候. 我们在顶层(即所有子部件之上)绘制一些东西. 
 // DeferOverlay() 的说明见本例子的 Board::DrawOverlay() 函数的声明处.
 if (mLostFocus)
  DeferOverlay(mDeferPriority); 

}

// 在顶层绘制
void Board::DrawOverlay(Graphics* g)
{ 
 g->SetColor(Color(0, 0, 255, 175));
 g->FillRect(0, 0, mWidth, mHeight);

 g->SetFont(FONT_DEFAULT);
 g->SetColor(Color::White);
 g->DrawString(_S("LOST FOCUS"), mMsgX, mMsgY); 

 // 调用下边的 PushState() 函数可以方便的保存 Graphics 对象的当前状态. 以便以后用 PopState() 恢复该状态.
 // (当调用 SetColor(), SetDrawMode() 等函数时都会改变 Graphics 对象的状态). 
 g->PushState();

 // 对比在第3个例子中. 有些状态设置后必须在不用的时候改回来(例如平滑拉伸等). 
 // 现在不用改回来了. 只要在不用的时候一个 g->PopState(); 就返回以前的状态了. 
 g->SetColorizeImages(true);
 g->SetColor(Color(0, 255, 255));
 

 // 在以前的例子中. 我们也对图像做过 缩放/旋转/镜像 绘制. 但那种办法很麻烦. 
 // 现在我们学习一种新的方法. 它使用一个转换器. 将要对图像做的操作都设置到转换器中. 
 // 然后绘制时使用 g->DrawImageTransform() 来绘制. 就可以得到想要的效果.

 // 转换器对象
 Transform t;

 // 指定转换器的旋转角度. 参数为需要旋转的角度数(0-360). 
 t.RotateDeg((float)(mUpdateCnt % 360));
 
 // 根据 Update次数来计算缩放的比例. 
 // x方向和y方向有各自的比例. 其值为 1.0 表示不缩放.
 // 若某个方向的缩放比例为负数. 则表示使用镜像(即左右颠倒或上下颠倒).
 float sw;
 float sh;
 int mod = mUpdateCnt % 200;
 if (mod < 100)
 {
  sw = (float)(mod + 1) / 100.0f;
  sh = (float)(mod + 1) / 100.0f;
 }
 else
 {
  mod = 200 - mod;
  sw = (float)mod / 100.0f;
  sh = (float)mod / 100.0f;
 }

 // 指定 transform 对象的缩放比例.  
 // 这里我们指定为负数. 即镜像图像.
 t.Scale(-sw, -sh);
 

 // 现在绘制图像. 
 // 通过g->DrawImageTransform/F(). 它的参数分别为: 
 //   要绘制的图像.
 //   转换器.
 //   x , y 坐标
 // 它在2D或3D模式中都可以工作. (这里的x,y坐标是目的图像的中心点吗?)
 if (gSexyAppBase->Is3DAccelerated())
  g->DrawImageTransformF(IMAGE_HUNGARR_LOGO, t, (float)(mUpdateCnt % (mApp->mWidth + 340)), 200.0f);
 else
  g->DrawImageTransform(IMAGE_HUNGARR_LOGO, t, (float)(mUpdateCnt % (mApp->mWidth + 340)), 200.0f);
 
 //恢复到调用g->PushState();之前的状态.
 g->PopState();

 // 下边讲的什么东西不懂.
 // You can now draw using matrices. Why the heck would you want to use matrices? Besides doing some
 // crazy stuff, you can also do some cool little tricks. For example, previously it used be a pain
 // to in real-time flip and mirror an image. While I won't give a tutorial on matrix algebra
 // (that would take a loooooong time), I'll explain the essential parts:
 SexyTransform2D matrix;


 // Multiplying the X coordinate by -1 (which is the 0, 0 element of the matrix) will result in our
 // image being mirrored, while multiplying the Y coordinate by -1 (1, 1 in the matrix) will result in our
 // image being flipped.
 matrix.m[0][0] *= -1;
 matrix.m[1][1] *= -1;

 // Let's also shear it. While mirroring/flipping could easily be done with the DrawImageTransform methods,
 // doing more complex matrix manipulation (like shearing) can only be done with the DrawImageMatrix function.
 matrix.m[0][1] = 2;

 // And then we just make a call to DrawImageMatrix and give it our specified XY coordinates as well,
 // and that's it! This works in both 2D and 3D modes.
 g->DrawImageMatrix(IMAGE_HUNGARR_LOGO, matrix, 300, 400); 

 // IMPORTANT COMPARISON NOTE:
 // DrawImageTransform/F will try to use the faster drawing methods if it recognizes certain
 // common transforms, like rotating and scaling. This only works though if you are using
 // either one operation, or multiple operations of the same type (i.e. you only used scale
 // or rotate with the Transform object, or used the same one multiple times). If you mix
 // operations, like we do above, the DrawImageTransform method will actually use DrawImageMatrix.
 // With DrawImageTransform, you can't directly modify the underlying matrix, so if that's something
 // you need to do, then DrawImageMatrix is a better option.
}

void Board::ButtonDepress(int id)
{
 if (id == mDemoButton->mId)
 {
  delete mDemoWidget;
  mDemoWidget = new DemoWidget();
  mApp->mWidgetManager->AddWidget(mDemoWidget);
  
  // What, more flags? Yup. Since our little DemoWidget isn't a dialog, when we add it,
  // it won't change anything about the widgets drawn below it. Which means, unmodified, 
  // mouse clicks could still be passed down to the board (if the click wasn't in the DemoWidget),
  // the board still updates, still draws, etc. Let's turn off mouse clicks for all widgets below the
  // DemoWidget. But, let's still allow all widgets below it to update. Note that if we used the form
  // of the method that only takes one parameter, then it would use mDefaultBelowModalFlagsMod
  // which we modified in our app. By passing in our own flags though, they're used instead.
  // Which means the only flag we need to remove from the widgets below it is the allow mouse flag.
  // We do that by making a temp FlagsMod object, and setting
  // its mRemoveFlags variable to be ORed with WIDGETFLAGS_ALLOW_MOUSE. Upon calling
  // the WidgetManager's AddBaseModal method, we then pass in the DemoWidget, and the above flags.
  // AddBaseModal will then treat this new widget as a modal object, applying any flags we passed in.
  FlagsMod flags;
  flags.mRemoveFlags |= WIDGETFLAGS_ALLOW_MOUSE;
  mApp->mWidgetManager->AddBaseModal(mDemoWidget, flags);
 }
 else if (id == mDialogButton->mId)
 {
  // 1.2版本增加了创建对话框的更简单的方法.
  // 以前在第5个例子中. 我们创建对话框前先要重写 SexyAppBase::NewDialog() 函数. 在其中指定缺省时对话框的皮肤,对话框按钮皮肤等...
  // 现在可以不必这样了. 我们可以创建没有皮肤的对话框. 这在快速原型开发或者测试时是很方便的.

  Dialog* d = mApp->DoDialog(100, true, _S("Fun Dialog"), _S("Line 1\nLine 2\nLine 3"), _S("Close!"), Dialog::BUTTONS_FOOTER);

  // 可以不指定其字体. 如果没有指定一个字体. 则对话框使用系统默认字体.
  // d->SetButtonFont(FONT_DEFAULT);
 }
 else if (id == mCurtainButton->mId)
 {
  mCurtainMode = CURTAIN_CLOSING;
  mCurtainWidth = 0;

   
  while ((mCurtainMode != CURTAIN_INACTIVE) && mApp->UpdateApp())
  {
   if (mCurtainMode == CURTAIN_CLOSING)
   {
    mCurtainWidth += 4;
    if (mCurtainWidth >= mWidth / 2)
    {
     mCurtainWidth = mWidth / 2;
     mCurtainMode = CURTAIN_OPENING;
    }
   }
   else
   {
    mCurtainWidth -= 4;
    if (mCurtainWidth <= 0)
    {
     mCurtainWidth = 0;
     mCurtainMode = CURTAIN_INACTIVE;
    }
   }

  }

 }
}
//DemoWidget.cpp


#include "DemoWidget.h"
#include "Res.h"
#include "SexyAppFramework/WidgetManager.h"
#include "SexyAppFramework/ButtonWidget.h"
#include "V12DemoApp.h"

using namespace Sexy;

//
//
DemoWidget::DemoWidget()
{

 // 调整大小
 int w = 200, h = 200;
 Resize(gSexyAppBase->mWidth / 2 - w / 2, gSexyAppBase->mHeight / 2 - h / 2, w, h);
 
 // 以前, 要把一个 widget 做为子窗口插入另一个 widget 是很烦人的. 
 // 所以以前的例子中你必须重写 AddedToManager/RemovedFromManager 函数....等等...
 // 现在可以直接在父部件的构造函数中创建子部件. 可以用成员函数 AddWidget() 将子部件插入. 
 // 而且. 在父部件的析够函数中. 也只要在 delete 子部件前加上一句 RemoveAllWidgets() 就可以方便的从部件管理器中移除所有子部件了. 

 mMoveButton = new ButtonWidget(0, this);
 mMoveButton->mLabel = _S("MOVE");
 mMoveButton->SetFont(FONT_DEFAULT);
 
 mCloseButton = new ButtonWidget(1, this);
 mCloseButton->mLabel = _S("CLOSE");
 mCloseButton->SetFont(FONT_DEFAULT); 

 // 方便的将 mMoveButton 做为该类对象的子部件. 
 AddWidget(mMoveButton);
 AddWidget(mCloseButton);

 mMoveButton->Resize(10, 150, 75, 50);
 mCloseButton->Resize(115, 150, 75, 50);

 // 部件的优先级(也就是 Z顺序). 缺省为0. 它越大越绘制在顶层.
 mPriority = 1;

}

//
//
DemoWidget::~DemoWidget()
{
 // 在delete 子部件们之前. 需要用 RemoveAllWidgets() 将所有子部件从部件管理器中 remove. 
 // 这个函数也可以带参数:
 //  RemoveAllWidgets(bool doDelete = false, bool recursive = false); 
 // 其中第一个参数为在移除子部件时. 是否顺便将其 delete...  这个也很有用..
 // 第二个参数为是否也递归的调用子部件的 RemoveAllWidgets() .

 RemoveAllWidgets();

 delete mMoveButton;
 delete mCloseButton;
}

//
//
void DemoWidget::ButtonDepress(int id)
{
 if (id == mMoveButton->mId)
 {
  // 现在. 要移动一个部件只要调用其 Move() 函数即可. 
  // 它在移动的时候也同时会自动的移动其内部的子部件. 
  // 但是在以前的版本中. 则只能手动的一个一个移动这些子部件. 
  Move(Rand() % (gSexyAppBase->mWidth - mWidth), Rand() % (gSexyAppBase->mHeight - mHeight));
 }
 else if (id == mCloseButton->mId)
 {
  // 从部件管理器中移除 "当前部件"自己.
  gSexyAppBase->mWidgetManager->RemoveWidget(this);
 }
}


//
//
void DemoWidget::Draw(Graphics* g)
{
 g->SetColor(Color(0, 255, 0, 200));
 g->FillRect(0, 0, mWidth, mHeight);


}

// v12DemoApp.cpp


#include "V12DemoApp.h"
#include "SexyAppFramework/WidgetManager.h"
#include "SexyAppFramework/DDImage.h"
#include "SexyAppFramework/ResourceManager.h"
#include "SexyAppFramework/Dialog.h"
#include "SexyAppFramework/SWTri.h"
#include "Board.h"
#include "Res.h"

using namespace Sexy;

V12DemoApp::V12DemoApp()
{
 mProdName = "V12Demo";
 mProductVersion = "1.0";
 mTitle = StringToSexyStringFast("SexyAppFramework: " + mProdName + " - " + mProductVersion);
 mRegKey = "PopCap\SexyAppFramework\V12Demo";

 mNoSoundNeeded = true;
 mBoard = NULL;
 
 // 必须调用下面的函数. 它告诉程序可以使用 DrawImageTransform 和 DrawImageMatrix 函数.
 // 为什么要手动调用? 因为如果不使用它们可以使exe文件减少 400K(压缩后150K). 所以提供了一个选择的机会.
 SWTri_AddAllDrawTriFuncs();
}

V12DemoApp::~V12DemoApp()
{
 delete mBoard;
}

void V12DemoApp::ShutdownHook()
{
 if (mBoard != NULL)
  mWidgetManager->RemoveWidget(mBoard);
}

void V12DemoApp::InitHook()
{ 
 LoadResourceManifest();
 
 if (!mResourceManager->LoadResources("Init"))
 {
  mLoadingFailed = true;
  ShowResourceError(true);
  return;
 }

 if (!ExtractInitResources(mResourceManager))
 {
  mLoadingFailed = true;
  ShowResourceError(true);
  return;
 }

 // This is new. Widgets now contain flags that alter the behavior of them.
 // Please read the document included with the 1.2 release for a full description,
 // but here's the general rundown:
 // The WidgetManager's mDefaultBelowModalFlagsMod contains flags that are applied
 // anytime a dialog box pops up on screen. If we modify these, then we modify the
 // default behavior for ALL dialog boxes, and don't have to mess around with other
 // function calls and setting of misc. variables. All flags variables contain 2
 // sub-variables: mAddFlags and mRemoveFlags. By ORing stuff with mAddFlags, when
 // a dialog box pops up, the flags in mAddFlags are applied in addition to any
 // other flags that exist. Similarly, mRemoveFlags contains flags that are removed
 // from a widget when the dialog pops up. Below, what we're saying is that when
 // a dialog box pops up, we DO NOT want any widgets beneath it to be able to update.
 // What'll happen is that any widget below the dialog gets the WIDGETFLAGS_UPDATE
 // flag removed. This will of course be restored when the dialog box closes.
 // Again, please see the 1.2 doc for a list of all the flags and a much more
 // thorough explanation.
 mWidgetManager->mDefaultBelowModalFlagsMod.mRemoveFlags |= WIDGETFLAGS_UPDATE;

 mBoard = new Board(this);
 mBoard->Resize(0, 0, mWidth, mHeight);
 mWidgetManager->AddWidget(mBoard);
}

void V12DemoApp::LostFocus()
{
 if (mBoard)
  mBoard->SetFocusLost(true);
}

void V12DemoApp::GotFocus()
{
 if (mBoard)
  mBoard->SetFocusLost(false);
}


// 新的对话框按钮事件处理方法:
// 只需在 app 类的DialogButtonDepress() 函数中检查 指定对话框的指定按钮. 就可以指定执行它的响应操作.
void V12DemoApp::DialogButtonDepress(int dialog_id, int button_id)
{ 
 if ((dialog_id == 100) && (button_id == Dialog::ID_OK))
  KillDialog(100);
}

//main.cpp


//
//      main.cpp
//
// ***********************************************************************
// 这个例子介绍1.2版的新特性.
//  当然. 你需要先看 例子1 到 例子5 学习一些基础的知识.
// ***********************************************************************
// 
// * 用新的 InitHook()/ShutdownHook() 来做初始化和退出时的工作. 而不再需要重写基类的 Init().
//
// * 在App类的 DialogButtonDepress() 中处理特定对话框的特定按钮事件. 
//
// * 可以在不指定皮肤的情况下创建对话框. 这在快速开发或调试的时候很有用.
//
// * 用 flags 修改 widget 的行为. 例如"总是marking dirty",  "不允许鼠标事件" 等.
//
// * 更简便的 将一个 widget 做为子窗口插入另一个 widget. 
//
// * 怎么在顶层绘制. 怎么绘制在所有部件之上. 怎么根据"优先级"确定它们的 Z 顺序.
//
// * push/pop graphics对象的状态.
//
// * 用新的 Graphics::DrawImageTransform/F 来更好的 旋转/缩放/转换图像.
//
// * 用新的 Graphics::DrawImageMatrix 绘制 2D/3D with a matrix.  
//
// * How to use UpdateApp to help with transitions 
//

#include "V12DemoApp.h"

using namespace Sexy;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
 gHInstance = hInstance;

 V12DemoApp* anApp = new V12DemoApp();
 anApp->Init();
 anApp->Start();
 delete anApp;

 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值