科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件托管C++程序开发—Win表单文档程序设计(下)

托管C++程序开发—Win表单文档程序设计(下)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

MFC的“文档/视图”机制最大的好处是可以很容易实现“一档多视”。但其内部机制是非常复杂

作者:Adding 来源:YESKY 2007年11月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

  二、窗格之间的数据传送

  由于两个窗格是由相应的控件来创建的,因而它们之间的数据传输可直接进行。例如下面的例子很有趣,其结果如图3所示。

...
__gc class WinForm: public Form
{
private:
Label *m_pLabelDraw;
Splitter *m_pSplitter;
Panel *m_pPanel;
NumericUpDown *m_pSpinX;
NumericUpDown *m_pSpinY;

int m_nRectX, m_nRectY;
bool m_bChanged;
public:
WinForm()
{
m_nRectX = m_nRectY = 10;
m_bChanged = true;
InitForm();
}
void Dispose()
{
Form::Dispose();
}
void InitForm()
{
Text = S"切分窗口的应用示例";
ClientSize = Drawing::Size(600, 400);

m_pLabelDraw = new Label();
m_pSplitter = new Splitter();
m_pPanel = new Panel();
m_pSpinX = new NumericUpDown();
m_pSpinY = new NumericUpDown();

// 构造左边的m_pPanel
Label *label1 = new Label();
label1->Location = Drawing::Point(24, 36);
label1->Size = Drawing::Size(24, 16);
label1->Text = "X = ";

m_pSpinX->Location = Drawing::Point(56, 32);
m_pSpinX->Size = Drawing::Size(72, 21);
m_pSpinX->Minimum = 10;
m_pSpinX->Maximum = 1000;
m_pSpinX->ValueChanged += new EventHandler(this, &WinForm::DoValueChanged);

Label *label2 = new Label();
label2->Location = Drawing::Point(24, 76);
label2->Size = Drawing::Size(24, 16);
label2->Text = "Y = ";

m_pSpinY->Location = Drawing::Point(56, 72);
m_pSpinY->Size = Drawing::Size(72, 21);
m_pSpinY->Minimum = 10;
m_pSpinY->Maximum = 1000;
m_pSpinY->ValueChanged += new EventHandler(this, &WinForm::DoValueChanged);

GroupBox *groupBox1 = new GroupBox();
groupBox1->Controls->Add(label1);
groupBox1->Controls->Add(m_pSpinX);
groupBox1->Controls->Add(label2);
groupBox1->Controls->Add(m_pSpinY);

groupBox1->Location = Drawing::Point(8, 18);
groupBox1->Size = Drawing::Size(160, 120);
groupBox1->TabStop = false;
groupBox1->Text = "坐标设置";

m_pPanel->Controls->Add(groupBox1);
m_pPanel->Size = Drawing::Size(176, 144);
m_pPanel->Dock = DockStyle::Left;

// 再将m_pSplitter、m_pPanel和m_pLabelDraw加入Controls容器中
m_pSplitter->TabStop = false;
m_pSplitter->Dock = DockStyle::Left;
m_pSplitter->BackColor = Drawing::Color::Green;

m_pLabelDraw->BackColor = Drawing::SystemColors::Window;
m_pLabelDraw->BorderStyle = BorderStyle::Fixed3D;
m_pLabelDraw->Dock = DockStyle::Fill;
m_pLabelDraw->MouseDown += new MouseEventHandler(this, &WinForm::DoMouseDown);

Controls->Add(m_pSplitter);
Controls->Add(m_pLabelDraw);
Controls->Add(m_pPanel);

Paint += new PaintEventHandler(this, &WinForm::OnPaint);
}

void DoMouseDown(Object *sender, MouseEventArgs *e)
{
if (e->Button == MouseButtons::Left){
m_nRectX = e->X;
m_nRectY = e->Y;
m_bChanged = false;
m_pSpinX->Value = m_nRectX;
m_pSpinY->Value = m_nRectY;
Invalidate();
m_bChanged = true;
}
}

void DoValueChanged(Object *sender, EventArgs *e)
{
if (m_bChanged) {
m_nRectX = (int)m_pSpinX->Value;
m_nRectY = (int)m_pSpinY->Value;
Invalidate();
}
}

void OnPaint(Object *sender, PaintEventArgs *e)
{
m_pLabelDraw->Update();
DrawUserRect();
}

void DrawUserRect(void)
{
Graphics* g = m_pLabelDraw->CreateGraphics();
SolidBrush* backSolid = new SolidBrush(Drawing::Color::White);
g->FillRectangle(backSolid,m_pLabelDraw->ClientRectangle);
SolidBrush* foreSolid = new SolidBrush(Drawing::Color::Blue);
g->FillRectangle(foreSolid,m_nRectX-10,m_nRectY-10,20,20);
}

};
...

              图3


  从上面的代码可以看出:

  (1) 若在控件中进行GDI+图形绘制时,需要调用控件Update方法,以避免系统更新它。这一点与MFC是相似的。

  (2) 由于当在右边窗口左击鼠标时,将鼠标的位置坐标传给NumericUpDown,此时NumericUpDown会产生ValueChanged事件,从而调用DoValueChanged,这使得整个界面的用户交互变得非常迟钝。因此,我们在这里使用m_bChanged变量来控制它,解决了上述问题。

  (3) 对于比上面还要复杂的应用程序,我们推荐使用MFC的文件组织形式以及根据MFC“文档/视图”机制的思想去设计我们相关的托管类。

  三、结束语

从前面的几篇文章,我们可以看出使用托管C++开发.NET应用程序是比较方便的,除了在Windows Forms可视化设计上略嫌不足(事实上,上述所有的控件布局都是通过Visual C#的窗口编辑器来进行的)。它的最大优点是代码短,编译速度奇快,生成的EXE文件也不大。当然,用托管C++开发.NET,其应用绝不止以上所述内容,以后将推出更多这样的文章,谢谢大家。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章