当我的程序不加断点运行时结果是错的,程序会选择桌面上最后一个文件夹;而加了断点后一步一步运行的话就能得到预期结果!
贴我的垃圾代码出来,我只想知道为什么要加断点才能得到预期的结果。BOOL SelectPath(CString path)
{
CStringArray strArr;
int k;
HWND hwnd;
CString text;
const int bufferLength = 4000;
DWORD processId = NULL;
LPTVITEM item = (LPTVITEM)new BYTE[bufferLength]; k = ReduceString(path,strArr);
hwnd = ::FindWindow(_T("#32770"),_T("test"));
hwnd = FindWindowEx(hwnd,NULL,_T("Button"),_T("..."));
::PostMessage(hwnd,BM_CLICK,0,0);
Sleep(1000);
hwnd = ::FindWindow(_T("#32770"),_T("浏览文件夹"));
hwnd = FindWindowEx(hwnd,NULL,_T("SHBrowseForFolder ShellNameSpace Control"),_T(""));
hwnd = FindWindowEx(hwnd,NULL,_T("SysTreeView32"),_T("Output directory"));
GetWindowThreadProcessId(hwnd,&processId);
HANDLE process = ::OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,false,processId);
PVOID buffer = VirtualAllocEx(process,NULL,bufferLength,MEM_COMMIT,PAGE_READWRITE);
item->mask = TVIF_TEXT;
item->cchTextMax = 512;
item->pszText = LPTSTR((PBYTE)buffer+sizeof(TVITEM));
item->hItem = (HTREEITEM)::SendMessage(hwnd,TVM_GETNEXTITEM,TVGN_ROOT,0);

while(item->hItem)
{
::SendMessage(hwnd,TVM_SELECTITEM,TVGN_CARET,(long)item->hItem);
WriteProcessMemory(process,buffer,item,sizeof(TVITEM),NULL);
::SendMessage(hwnd,TVM_GETITEM,0,(LPARAM)buffer);
ReadProcessMemory(process,buffer,item,bufferLength,NULL); text = (LPTSTR)((PBYTE)item+sizeof(TVITEM)); if( text.Find(":") != -1)
{
text = text.Mid(text.Find(":")-1,2);
} Sleep(100);
if( text == strArr[0] )
{
for(int i = 1; i<=k; i++)
{
::SendMessage(hwnd,TVM_EXPAND,TVE_EXPAND,(long)item->hItem);
item->hItem = (HTREEITEM)::SendMessage(hwnd,TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,(long)item->hItem);
while(item->hItem)
{ ::SendMessage(hwnd,TVM_SELECTITEM,TVGN_CARET,(long)item->hItem);
WriteProcessMemory(process,buffer,item,sizeof(TVITEM),NULL);
::SendMessage(hwnd,TVM_GETITEM,0,(LPARAM)buffer);
ReadProcessMemory(process,buffer,item,bufferLength,NULL);
text = (LPTSTR)((PBYTE)item+sizeof(TVITEM));

if( text == strArr[i] )
{
break;
}
else
{
item->hItem = (HTREEITEM)::SendMessage(hwnd,TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,(long)item->hItem);
}
}
}
Sleep(2000);
hwnd = ::FindWindow(_T("#32770"),_T("浏览文件夹"));
hwnd = FindWindowEx(hwnd,NULL,_T("Button"),_T("确定"));
::PostMessage(hwnd,BM_CLICK,0,0);
return true;
} else
{
item->hItem = (HTREEITEM)::SendMessage(hwnd,TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,(long)item->hItem);
}
}
return true;
}
int ReduceString(CString path,CStringArray &strArr)
{
CString childPath;
strArr.SetSize(100,1024);
int i = 0;
int j = 0; while( path.Find("\\",i+1) != -1 )
{
if(i == 0) 
{
childPath = path.Mid(i,path.Find("\\",i+1) - i);
i = path.Find("\\",path.Find("\\",i+1));
strArr.SetAt(j,childPath);
j++;
continue;
}
childPath = path.Mid(i+1,path.Find("\\",i+1) - i -1);
i = path.Find("\\",path.Find("\\",i+1));
strArr.SetAt(j,childPath);
j++;
} strArr.SetAt(j,path.Mid(path.ReverseFind('\\')+1,strlen(path)-path.ReverseFind('\\')));

return j;
}

解决方案 »

  1.   

    把里面的PostMessage改成SendMessage试试。
      

  2.   


    呵呵,等待方式不然把SendMessage改成PostMessage再试试再有WriteProcessMemory ReadProcessMemory等操作应该判断下是否成功,很容易这些操作就失败的
      

  3.   

    楼上两位的办法都试过了,不行,本来WriteProcessMemory ReadProcessMemory是有判断的,不过鉴于加上后太累赘所以没加,还有办法吗各位高手们!?
      

  4.   

    Log过程(结果)到文件或者Trace, 看在哪出错
      

  5.   

    FOR里面加了SLEEP也没用,这些方法都试过,请问4楼怎么TRACE?我不太懂...
      

  6.   

    系统的浏览文件夹对话框中,每个文件夹都是在第一次展开的时候,才去搜索并添加子文件夹的,所以需要一些时间,你试试在发TVM_EXPAND消息之后Sleep一段时间再继续执行。
    另外,你可以在每个SendMessage之后都Sleep一两秒钟时间,看看程序控制的过程是在哪里出错。
      

  7.   

    终于解决了,不过只是这台电脑上能正常运行,其它电脑又不行了,都是XP的系统,看来很不稳定的确是延时的问题,应该在每个IF(...)前加SLEEP