在用 win32 API 学习 windows 编程。想做一个简单的日记本:主窗体的左侧是一个 treeview 控件,显示日记目录,右侧是一个 richedit 控件,显示日记内容。想给 treeview 控件添加一个右键菜单,但是失败了。部分代码如下:HMENU hMenu ;int WINAPI WinMain(  HINSTANCE hInstance, ... )
{
...
hInst = hInstance ;
...
}
LRESULT CALLBACK WndProc( ... )
{
...
switch( message )
{
case WM_CREATE :
...
hMenu = LoadMenu( hInst, TEXT("TreeViewMenu") ) ;
hMenu = GetSubMenu( hMenu, 0 ) ; 
...
}
}LRESULT CALLBACK TreeViewProc(...)
{
POINT point ; switch( message )
{
case WM_RBUTTONDOWN :
point.x = LOWORD(lParam) ;
point.y = HIWORD(lParam) ;
ClientToScreen( hTreeView, &point ) ; 
// 这里用 hTreeView 对吗?应该是 GetParent(hTreeView) ?

TrackPopupMenu( hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, 
GetParent(hTreeView), NULL ) ; 
// 这里用 GetParent(hTreeView) 对吗?
break ;
...
}
}上下文菜单属于主窗口还是子窗口?我把上面的几处 hTreeView 和 GetParent(hTreeView) 的几种组合都试了一下,还是不行。错在哪里?请指教。还有几个小问题:1.只使用 richedit 控件的时候,EM_CHANGE 消息有效,但是当我同时使用 treeview 控件的时候,每次重新激活窗口或者改变窗口大小都会产生一个 EM_CHANGE 消息,比如先最小化窗口再显示窗口。不知道原因,我只好在需要保存的时候将备份文本和richedit中的相比较,判断是否修改了文本。2.下面是我读取 richedit 文本内容的代码:
int length = GetWindowTextLength( hEdit ) ;
PTSTR text = static_cast<PTSTR>(malloc((length+2) * sizeof(TCHAR))) ;
if( ! text )
{
outError( TEXT("Insuffcient memory available!") ) ;
return NULL ;
}
GetWindowText( hEdit, text, length + 1 ) ;
text[length+1] = TEXT('\0') ;
注意到里面奇怪的 length + 2 、length + 1 没有?只有这样才能正确读取。我哪里做错了?3.vc6.0 的 fstream 是不是有 bug ? 我在用 它的 fstream 读取写入文件的时候,发现根本不行。对同一个文件做  读 -- 写 -- 读 ,我测试发现不行(每次读写完成后都要关闭文件)。用 bcc55 编译运行就可以。后来我只好用 fread、fwrite 重写了。4.发现我的程序占用内存远远多于 editplus, 我测试发现好像只创建一个窗口占用的内存都不少,editplus 的空间效率怎么那么好?请大家指教。5.如果用 C# 来完成效率应该高很多,但是 C# 可以编译成本机代码吗?

解决方案 »

  1.   

    沙发,就让姐姐我来答:应该用GetCursorPos(&point)代替ClientToScreen( hTreeView, &point ) ,在TrackPopupMenu()中应该用子窗口的句柄。
      

  2.   

    to ShanChunZhenZi(山村贞子) :
    刚才试了下,还是不行。改用 WM_CONTEXTMENU 消息,也不行,而且效果和 WM_RBUTTONUP 一样,都要双击右键才有响应( 我加了一个消息框),没有菜单出现。WM_RBUTTONDOWN 好一些,每次右键单击都有反应,但是也没有弹出菜单。我看的是 petzold 的 <<windows 程序设计>>,里面关于上下文菜单的例子只有一个主窗口。还有,我想用 StreamIn Out 来读写 richedit 的内容,也失败了。MS 的文档里说 当“The value returned in the *pcb parameter is less than the number of bytes requested in the cb parameter” 时,richedit 会结束对 EditStreamCallback 的调用,但是我让 *pcb = 50,它也没有结束调用,让 *pcb = 0 才结束,但是 richedit 上面没有一个字符出现。下面是我的回调函数:DWORD CALLBACK EditStreamIn( DWORD sourceStr, LPBYTE pbBuff, LONG numBytes, LONG *pBytesRead )
    {
    PTSTR *str = reinterpret_cast<PTSTR *>(sourceStr) ;
    int bytesRead = 0 ;
    int length = _tcslen(*str) ; if( length >= numBytes )
    bytesRead = numBytes ;
    else
    bytesRead = length ; _tcsncpy( reinterpret_cast<PTSTR>(pbBuff), *str, bytesRead ) ;
    str += bytesRead ;
    *pBytesRead = bytesRead ;

    return 0 ;
    }
      

  3.   

    上下文菜单和 stream in out 的问题解决了,但是其他几个还没有。
      

  4.   

    TrackPopupMenu()中应该用子窗口的句柄,hTreeView 和 子窗口过程参数 hwnd 有什么不同呢?我改成 hwnd ,treeview 的上下文菜单才显示出来。