环境: VC8 SDK我程序中有一个树型视图控件和一个RichEdit控件。每点击TreeView控件上的一个结点,程序就会向RichEdit控件中导入相应的文本。之后根据相关记录发送一个EM_SETSCROLLPOS将文本的滚动条滚动到对应位置。奇怪的是EM_SETSCROLLPOS并不能实现我的要求,滚动条变化不大(我有的文本较长,滚动位置可达一万多,但EM_GETSCROLLPOS发现只滚动了2000)。我曾试验是不是我传给EM_SETSCROLLPOS的数据有误,于是用了一个能显示格式化数据的消息框测试(放在EM_SETSCROLLPOS前),结果发现数据正确,关闭消息框---伊,滚动成功了。去掉消息框再试---又失效了。最后我发现,只要在EM_SETSCROLLPOS前加个消息框(比如最普通的MessageBox),那么关闭消息框后滚动就能成功。否则失效。 MessageBox(...); //有这行下面代码就有效,去掉这行下面代码就无效。其它无变化
 SendMessage(hwndEdit,EM_SETSCROLLPOS,0,(LPARAM)point);
真是奇怪,请高手指点!

解决方案 »

  1.   

    把这个MessageBox用一个Sleep(1000)试试。
      

  2.   

    SendMessage(hwndEdit,EM_SETSCROLLPOS,0,(LPARAM)point);
    EM_SETSCROLLPOS消息的LPARAM参数应该是一个指向POINT结构变量的指针,不知道你这个point是什么。
      

  3.   

    发送消息之后刷新一下试试:
    SendMessage(hwndEdit,EM_SETSCROLLPOS,0,(LPARAM)point);
    InvalidateRect(hwndEdit,NULL,TRUE);
      

  4.   

    你这个MessageBox(...)里是什么?
    能不能把...里的东西列出来看看?
      

  5.   

    感谢各位回贴,问题已找到。解决方法有一个,虽然不完美,但还是可用:问题的原因是:在响应TreeView控件的项目点击时从文件中读取数据放入edit控件。请注意,这时edit控件需要做些更新(系统来做),这些更新操作需要在本条消息处理(响应TV的项目点击)完后才能进行。这是由window消息机制决定的(处理完一个消息再处理下一个)。那为什么放个消息框就可以了呢?为了响应用户操作,对话框内置了个消息循环处理机制,这个消息循环读取并处理了用来更新edit的消息,从而使后续滚动操作得以成功。所以解决方法可以是:
     DWORD  startTime,nowTime ;
     MSG  msg;
     startTime=time.GetTickCOunt();
     while (GetMessage(&msg, NULL, 0, 0))
     {
        nowTime=time.GetTickCOunt();
        if( (nowTime-startTime)>400 )
        {break;}
        TranslateMessage(&msg);
        DispatchMessage(&msg);
     }
     edit.SetScrollPos( & scii[i].scroll);
    美中不足的是,我无法判定哪条消息后edit就能完成更新,所以只好用400毫秒来执行消息队列中的消息,时间越长,越能确保edit完成状态更新,但界面响应就越慢。另外说一下:换PostMessage(hwndEdit,EM_SETSCROLLPOS,0,(LPARAM)point); 
    似乎可以,因为它并不阻碍程序继续往下走。遗憾的是实际上它不行。我猜原因可能是为了完成edit更新,系统向消息队例中添加的消息排在了PostMessage->EM_SETSCROLLPOS后面。各位还有何见解请指教,我准备近日结贴:)
      

  6.   

    谢谢楼主指点,Sleep()主的要原因就是延时,但是我忽略了这些更新操作需要在本条消息处理(响应TV的项目点击)完后才能进行。这一点。
      

  7.   

    焦点被截取,你可以往这方面试试,    MessageBox()调用后焦点被夺后,然后就行得通了。  因为上次碰到剪切板问题也是MessageBox()调用后就可以了