如何在窗口过程中处理子控件WM_PAINT消息。

时间:2020-12-29 20:38:10
窗口是使用标准API创建的。主窗口内包含若干子控件,其中有一个Picture Control。
如果能处理这个(Picture Control)子控件的WM_PAINT消息呢?
因为不光这个控件有WM_PAINT消息,其它子控件也有可能有WM_PAINT消息,我如何区分这个WM_PAINT消息是由Picture Control产生的?

另外,如何给Picture Control更改图像呀?

16 个解决方案

#1


帮up

#2


谢谢楼上的,如何解决呀?
我急用,大家帮帮忙啊,谢谢!

#3


图像控件你设置好了以后,窗体会自己更新
更换图像,在窗体的窗口过程中处理WM_COMMAND
举个例子比如WndProc是窗口过程
BOOL __stdcall WndProc(...)
{
    switch(message)
    {
       case ...:
          break;
       ...
       case WM_COMMAND:   //在这个消息里面处理更改图片
           switch(LOWORD(wParam)
          {
              case IDC_CHANGEPIC://假设消息ID为这个
                   //IDC_BMPXXX是你要更换的图片的资源ID,hBitmap是图片的句柄
                   hBitmap = LoadBitmap(hInstance,"XXX.bmp");
                   SendDlgItemMessage(hWnd,IDC_BMPXXX,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitmap);
                 break;
          }
       ...
}

#4


谢谢楼上的,我知道“图像控件你设置好了以后,窗体会自己更新”,我的程序是运行在WINCE上的,WINCE上的Picture Control不支持JPG,GIF,PNG等这样的压缩格式。所以我要自己解码然后得到Picture Control的DC画上去。

问题是怎么能够处理Picture Control的WM_PAINT消息呢?

#5


这个,使用MFC类,可以这样
//先取得Picture Contorl的rect
CRect rect;
m_picture.GetClientRect(&rect);     

CImage image;
image.Load(path);
CDC* pDC = m_picture.GetWindowDC();
image.Draw( pDC -> m_hDC,rect);   

然后要在窗口的WM_PAINT消息内,更新图像显示
::UpdateWindow(); //这一步很重要
...//这里再重新绘制Picture Control
   

#6


回复:shangguanwaner 
关键是我没有用MFC呀。我的窗口是用标准API创建的。
并且当WM_PAINT消息发生时,也不知道这个消息是由哪个子控件引发的啊?因为其它子控件也有可能会引发WM_PAINT消息呀?

#7


当父窗口重绘时,你的Picture control也要重绘,就在父窗口的WM_PAINT里更新Picture Control就可以了

#8


不行的,我试了。

case WM_PAINT:
if(GetDlgCtrlID(hwndDlg)==IDC_DVC_VCPIC)
{
//这里执行重画
}
//意思就是,如果控件ID是Picture control的话则执行自己的重绘代码。


可是我在if里面下了断点,就是进不去!!

#9


直接在case WM_PAINT:下执行Picture Control的绘制

因为你要自己绘制,所以,主窗口重绘的时候,相应的Picture Control也要重绘

#10


if(GetDlgCtrlID(hwndDlg)==IDC_DVC_VCPIC)
这句去掉,试试

#11


引用 10 楼 shangguanwaner 的回复:
if(GetDlgCtrlID(hwndDlg)==IDC_DVC_VCPIC) 
这句去掉,试试

去掉当然行了,不过这个WM_PAINT消息就不能保证是由Picture Control引发的了啊。

#12


不需要知道这个WM_PAINT是不是由Picture Control引发的,只要窗体要重绘制,你的Picture Control也必须重绘

#13


引用 12 楼 shangguanwaner 的回复:
不需要知道这个WM_PAINT是不是由Picture Control引发的,只要窗体要重绘制,你的Picture Control也必须重绘


怎么不需要知道啊?MFC中还可以单独指定要处理哪个控件的WM_PAINT消息呢呀。

#14


windows提供的纯粹控件可以认为是没有自己的消息循环的,只相当于一个中转。
PAINT放主窗口的消息循环中中处理即可。
根据无效区域判断所属的窗口,win下没有这种API。但控件隶属主窗体的范围,它需要重绘时主窗体的消息循环都可以接收到PAINT。
必须只在图片无效时才重绘可以自己获取无效区域的范围,以及得到目标控件的范围并判断。

#15


看了[xiaopoy]的回答明白点了。
原来控件还有自己的消息循环,以前我还以为所有放到主窗口上的控件都和主窗口共用一个消息循环呢。

#16


该回复于2009-03-13 09:07:23被版主删除

#1


帮up

#2


谢谢楼上的,如何解决呀?
我急用,大家帮帮忙啊,谢谢!

#3


图像控件你设置好了以后,窗体会自己更新
更换图像,在窗体的窗口过程中处理WM_COMMAND
举个例子比如WndProc是窗口过程
BOOL __stdcall WndProc(...)
{
    switch(message)
    {
       case ...:
          break;
       ...
       case WM_COMMAND:   //在这个消息里面处理更改图片
           switch(LOWORD(wParam)
          {
              case IDC_CHANGEPIC://假设消息ID为这个
                   //IDC_BMPXXX是你要更换的图片的资源ID,hBitmap是图片的句柄
                   hBitmap = LoadBitmap(hInstance,"XXX.bmp");
                   SendDlgItemMessage(hWnd,IDC_BMPXXX,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitmap);
                 break;
          }
       ...
}

#4


谢谢楼上的,我知道“图像控件你设置好了以后,窗体会自己更新”,我的程序是运行在WINCE上的,WINCE上的Picture Control不支持JPG,GIF,PNG等这样的压缩格式。所以我要自己解码然后得到Picture Control的DC画上去。

问题是怎么能够处理Picture Control的WM_PAINT消息呢?

#5


这个,使用MFC类,可以这样
//先取得Picture Contorl的rect
CRect rect;
m_picture.GetClientRect(&rect);     

CImage image;
image.Load(path);
CDC* pDC = m_picture.GetWindowDC();
image.Draw( pDC -> m_hDC,rect);   

然后要在窗口的WM_PAINT消息内,更新图像显示
::UpdateWindow(); //这一步很重要
...//这里再重新绘制Picture Control
   

#6


回复:shangguanwaner 
关键是我没有用MFC呀。我的窗口是用标准API创建的。
并且当WM_PAINT消息发生时,也不知道这个消息是由哪个子控件引发的啊?因为其它子控件也有可能会引发WM_PAINT消息呀?

#7


当父窗口重绘时,你的Picture control也要重绘,就在父窗口的WM_PAINT里更新Picture Control就可以了

#8


不行的,我试了。

case WM_PAINT:
if(GetDlgCtrlID(hwndDlg)==IDC_DVC_VCPIC)
{
//这里执行重画
}
//意思就是,如果控件ID是Picture control的话则执行自己的重绘代码。


可是我在if里面下了断点,就是进不去!!

#9


直接在case WM_PAINT:下执行Picture Control的绘制

因为你要自己绘制,所以,主窗口重绘的时候,相应的Picture Control也要重绘

#10


if(GetDlgCtrlID(hwndDlg)==IDC_DVC_VCPIC)
这句去掉,试试

#11


引用 10 楼 shangguanwaner 的回复:
if(GetDlgCtrlID(hwndDlg)==IDC_DVC_VCPIC) 
这句去掉,试试

去掉当然行了,不过这个WM_PAINT消息就不能保证是由Picture Control引发的了啊。

#12


不需要知道这个WM_PAINT是不是由Picture Control引发的,只要窗体要重绘制,你的Picture Control也必须重绘

#13


引用 12 楼 shangguanwaner 的回复:
不需要知道这个WM_PAINT是不是由Picture Control引发的,只要窗体要重绘制,你的Picture Control也必须重绘


怎么不需要知道啊?MFC中还可以单独指定要处理哪个控件的WM_PAINT消息呢呀。

#14


windows提供的纯粹控件可以认为是没有自己的消息循环的,只相当于一个中转。
PAINT放主窗口的消息循环中中处理即可。
根据无效区域判断所属的窗口,win下没有这种API。但控件隶属主窗体的范围,它需要重绘时主窗体的消息循环都可以接收到PAINT。
必须只在图片无效时才重绘可以自己获取无效区域的范围,以及得到目标控件的范围并判断。

#15


看了[xiaopoy]的回答明白点了。
原来控件还有自己的消息循环,以前我还以为所有放到主窗口上的控件都和主窗口共用一个消息循环呢。

#16


该回复于2009-03-13 09:07:23被版主删除