OnCreate与OnInit,OnDraw与OnPaint

本文介绍了MFC程序设计中OnCreate与OnInitialUpdate、OnDraw与OnPaint的区别和作用。OnCreate负责创建视图的基本结构和变量,OnInitialUpdate用于视图初始化。OnDraw作为通用的绘图函数,不受设备限制,而OnPaint专门处理WM_PAINT消息,用于屏幕绘制。在处理WM_PAINT时,应避免重复创建CPaintDC实例,并调用OnDraw完成绘图操作。

文章转自:

http://www.cnblogs.com/pure/archive/2010/09/21/1832705.html

 

两者先后顺序不同,构造函数生成本类的对象,但没有产生窗口,OnCreate后窗口产生, 然后才是视图的OnInitialUpDate,一般在这里对视图的显示做初化。

OnCreate只是产生VIEW的基本结构和变量,而在OnInitialUpDate中,主要对视图中控件等各个变量进行初始化操作。

例:我们要在视图中添加一个button和combobox控件,则

 

OnCreate函数中写法如下:

int CFormView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
  if (CView::OnCreate(lpCreateStruct) == -1)

    return -1;
  // TODO: Add your specialized creation code here
  CRect rect(20,20,100,50);
  m_ctrlButton.Create("Button1",WS_CHILD|WS_VISIBLE,rect,this,NULL);

  CFont *pFont=CFont::FromHandle((HFONT)::GetStockObject(ANSI_VAR_FONT));
  CRect rect1(150,20,350,100);
  m_combobox.Create(WS_CHILD|WS_VISIBLE|CBS_SIMPLE|CBS_NOINTEGRALHEIGHT|WS_VSCROLL,rect1,this,NULL);

  return 0;
}


OnInitialUpDate中写法
void CFormView::OnInitialUpdate() 
{
  CView::OnInitialUpdate();

  // TODO: Add your specialized code here and/or call the base class
  //初始化组合框控件
  m_combobox.AddString("Mondy");
  m_combobox.AddString("Tuesday");
  m_combobox.AddString("Wednesday");
  m_combobox.AddString("Thursday");
  m_combobox.AddString("Saturday");
  m_combobox.AddString("Sunday");

}

 

  在MFC程序设计中,按照传统的设计,如果处理WM_PAINT消息,一般会派生一个OnPaint函数,映射到WM_PAINT消息上进行绘图处理。但是很多程序中并没有出现OnPaint,一个OnDraw函数做了更多的绘图操作。而在消息映射的列表中,也没有见到WM_PAINT到OnDraw的映射。

  实际上,OnDraw不是OnPaint的映射,出现OnDraw,是为了实现各种不同的设备上的绘图一致性。

  首先,读者需要明白的是,WM_PAINT消息是为了绘制屏幕而出现的,因此,在OnPaint中,我们只能存取屏幕DC,进行绘制,常见的代码是:

  void MyWnd::OnPaint()

  {

    CPaintDC dc(this);

    //draw code here

  }

  这里的CPaintDC的构造函数会自动调用BeginPaint,获得一个屏幕DC,并附加在dc对象上。当dc对象析构时,系统自动调用EndPaint并使invalidated rectangle变成validated状态,从而结束绘制。(注意,重复创建CPaintDC实例会失败也因为如此)

  如果我们在OnPaint中绘制,那么在打印机上绘制我们就需要再写一个OnPrint函数,重新绘制。这样,程序设计者就需要维护两套代码。为了简化操作,MFC框架把大部分绘制操作都放在OnDraw中,OnPaint和OnPrint只构造相应的DC,然后分别调用OnDraw.也就是说,OnDraw适用于所有的设备,而OnPaint只适用于屏幕。

  大家在设计过程中必须注意:OnDraw是被基类的OnPaint主动调用的,如果你继承了OnPaint,你应该要么调用基类的OnPaint(此前不得创建CPaintDC实例,也不得调用BeginPaint),要么自己创建CPaintDC实例,并调用OnDraw.

<think>我们参考了上述提供的引用内容,特别是引用[1]、[2]、[4]、[5]中关于Service生命周期方法的描述。用户询问的是onCreateonInit、onStartCommand的调用机制顺序,但请注意,在标准的Android Service中,并没有名为`onInit`的方法。我们推测用户可能是笔误,或者指的是其他方法(如`onBind`),但根据上下文,我们只讨论标准方法。 根据引用内容,我们可以总结如下: 1. 当通过`startService()`启动Service时: - 如果Service是第一次启动,则调用顺序为:`onCreate()` → `onStartCommand()`(并且在某些版本中还会调用`onStart()`,但`onStart()`已在API level 5后被废弃,现在主要使用`onStartCommand()`)。 - 如果Service已经运行,则再次调用`startService()`只会触发`onStartCommand()`,而不会再次调用`onCreate()`。 2. 关于`onStartCommand()`的返回值(引用[2]提到): - `START_STICKY`:如果Service被系统杀死,系统会尝试重新创建Service,并调用`onStartCommand()`,但此时传入的Intent可能为null。 - `START_NOT_STICKY`:Service被杀死后不会自动重新创建。 - `START_REDELIVER_INTENT`:系统会重新创建Service,并且重新传递最后一个Intent给`onStartCommand()`。 3. 另外,引用[3]提到了ApplicationContentProvider的创建顺序,但用户的问题是关于Service的,因此我们主要关注Service的生命周期。 4. 引用[5]给出了一个简单的Service示例,其中包含`onCreate()`, `onStartCommand()`, `onDestroy()`方法。 因此,我们回答用户的问题如下: 在Android Service中,当通过`startService()`启动服务时: - `onCreate()`:在Service首次创建时调用,且在整个生命周期中只调用一次。用于进行一次性初始化设置。 - `onStartCommand()`:每次通过`startService()`启动服务时都会调用(包括首次启动)。该方法用于处理传递给服务的Intent,例如启动指令或需要处理的任务。 注意:没有`onInit`方法。如果用户指的是`onBind`方法,那么这是在通过`bindService()`绑定服务时调用的,用于返回一个IBinder接口给客户端。 调用顺序: 首次启动:`onCreate()` → `onStartCommand()` 后续启动:`onStartCommand()`(跳过`onCreate()`) 此外,当服务被销毁时,会调用`onDestroy()`。 关于`onStartCommand()`的返回值,它决定了当服务被系统意外杀死时的行为。 我们根据引用内容回答,并在引用处添加引用标识。 </think>### Android Service中onCreate、onStartCommand的调用机制及顺序 在Android Service生命周期中,**不存在`onInit`方法**(可能是笔误或混淆)。核心方法为`onCreate()``onStartCommand()`,调用顺序遵循以下规则: #### 1. 服务首次启动(通过`startService()`) 调用顺序为: ```mermaid graph LR A[onCreate] --> B[onStartCommand] ``` - **`onCreate()`**:仅调用一次,用于一次性初始化(如创建线程、绑定资源)[^1][^5] - **`onStartCommand()`**:立即执行,接收启动服务的`Intent`参数[^2][^4] 示例日志: ``` onCreate方法 onStartCommand方法 ``` #### 2. 服务已启动时再次调用`startService()` 仅触发: ```mermaid graph LR C[onStartCommand] ``` - **不会再次调用`onCreate()`**,直接执行`onStartCommand()`[^1][^4] - `onStartCommand()`可被多次调用(每次`startService()`触发一次)[^1][^2] #### 3. `onStartCommand()`返回值机制 返回值控制服务被系统杀死后的行为[^2]: | 返回值 | 行为 | |----------------------|----------------------------------------------------------------------| | `START_STICKY` | 系统重建服务,但`Intent`可能为null | | `START_NOT_STICKY` | 系统不自动重建服务 | | `START_REDELIVER_INTENT` | 系统重建服务并重发最后一次`Intent` | #### 4. 服务销毁 调用`onDestroy()`释放资源[^5]。 > ⚠️ 注意: > - `onStart()`已废弃(API Level 5+),由`onStartCommand()`替代[^2][^4] > - `bindService()`会触发`onCreate()`→`onBind()`,`startService()`独立[^2]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值