C++Builder 程序员博客
3 Sep
BCB中的ExtractFilePath()函数可以得到应该程序的当前目录,我要得到应用程序的上一级目录,在BCB中有没有函数可以直接得到的?
"C:\Program files\kk\Mypro.exe"
"C:\Program files\..\"
"C:\Program files"
把第一行去掉后面两个"\"以后的内容,然后加上"..\"得到第二行的内容,
第二行就等同于第三行
AnsiString str=ExtractFilePath(Application->ExeName);
str=str.Delete(str.Length(),1);//去掉最后一个"\"
str=ExtractFilePath(str);//注意根目录的情况
#include <string>
using namespace std;
/*取父路径函数*/
AnsiString GetParentPath(const AnsiString& path)
{
string strPath=path.c_str();
string::size_type pos1,pos2;
pos1=strPath.rfind("\\");
if(pos1!=string::npos)
{
if(pos1==strPath.length()-1)//是E:\test\test\这种情况
{
pos2=strPath.rfind("\\",pos1-1);
if(pos2!=string::npos)
return strPath.substr(0,pos2).c_str();
}
else if(pos1 <strPath.length()-1)//是E:\test\test这种情况
{
return strPath.substr(0,pos1).c_str();
}
}
return "";
}
写个递归就好了
void ExtractParentPath(String&FinalPath)
{
FinalPath.delete(1,FinalPath.Pos("\\");
if(FinalPath.Pos("\\")
ExtractParentPath(FinalPath);
}
调用上述过程
比如说在按钮事件中加入
String FilePath=GetCurrentDir();
String FinalPath=FilePath;
ExtractParentPath(FinalPath);
FilePath.Delete(FilePath.Length()-FinalPath.Length()+1,FinalPath.Length());
这个FilePath就百分百是你的程序目录的上一级目录了.
记得好像有倒过来搜索的过程的.不过不记得怎样做了.倒就过就方便多了.一句Delete就摆平了.
ExtractFilePath(FileName:String) 该函数返回路径名,其结尾字符总是“\”
ExtractFileDir(FileName:String) 该函数同样返回路径名,但不包括结尾的字符“\”,除非返回的路径是根目录。
ExtractFileDrive :返回完整文件名中的驱动器,如"C:"
ExtractFilePath:返回完整文件名中的路径,最后带“/”,如"C:\test\"
ExtractFileDir:返回完整文件名中的路径,最后不带“/” ,如"C:\test"
ExtractFileName:返回完整文件名中的文件名称 (带扩展名),如"mytest.doc"
ExtractFileExt 返回完整文件名中的文件扩展名(带.),如".doc"
楼上的大哥似乎理解错楼主想要的路径
c:\aaa\bbb\ccc\XXX.exe
楼主想要的是c:\aaa\bbb或者是c:\aaa\bbb\
系统提供的一个都没有
AnsiString str=ExtractFilePath(Application->ExeName);
str=str.SubStr(1,str.Length()-1);//去掉最后一个"\"
str=str.SubStr(1,str.LastDelimiter("\\"));//去掉最后一个"\"
29 Aug
8月可能见不到了。
嗯,说对了,哈哈哈
出来了也不是免费的 ,还得等待
jf,期待中。。。
接分
期待
不是说BCB不再开发新版本了吗?真的有2009?狂喜
严重期待!
有d版,如果再有人搞個e版就更熱鬧了。A版就沒人要?
反正9月也快到了
没有听说啊 !
以前曾经有过这么一说。
俺不急,9月10月都行,关键是要能火起来
无所谓,只要能超级稳定好用,年底出来也行!
不急,我还用着CB6呢
光打雷不下雨,25号发布现在一点动静都没有
……
这几天刚从cb6升级到cb2007,先熟悉一下。为了迎接新的2009.
驴子上只有2007的,还都是构架师版本的。专业版的都没有。呵呵。
哎,强弩之末了,但愿C++Builder慢慢恢复元气,以后不要搞这种虚张声势的动作了
jf
你的消息太落后了,已经出过BCB2006,2007了。
总得先做做宣传
期待2009的D,哈哈
d版是什么版本啊,a版,e版又什么意思。本人小鸟,高人指点下
已经安装完毕,版本号: 12.0.3155.16733,看起来和2007差不多。
25 Aug
需要从一个数据库的三个表中查询得到三条记录(一表一条)
能把它们写到一个txt文件中么?
搜到的帖子貌似都是讲怎样从一个表里面导出来的数据写到txt中
不知道不同表能不能写到一个文件里
当然,过程可逆,也就是说导出来还可以再导进去
C++ Builder刚开始学,各位高手赐教啊
去sql版块问吧,应该是可以得,用sql查询语句可以把多表结果合为一个结果集并输出为txt,excel等文档格式
最好写一个存储过程,这样所有集合在存储构成中执行好。
当然可以!可以找到很多的存储过程函数的!思路很简单:就是把找到的下一个数据加到原有数据后面!比如:
String value;
TStringList *t=new TStringList();
t-> LoadFromFile("监控记录.txt");
for (int i=0;i < t-> Count;i++)
{
value+=t-> Strings[i];
Memo1->Text=value;
}
delete t;
但此处仅仅是输出之前的!你可以找找完整的存储和输出过程函数!
感谢各位啊…
8 Aug
在一个frame的网页下,如何得到各个窗体上控件的name,
以及使用OlePropertyGet和OleFunction如何调用他们呢
没弄过,帮顶.
该回复于2008-07-19 16:14:14被版主删除
该回复于2008-07-10 02:45:59被版主删除
6 Aug
我在一个程序里要得到系统日期.知道有相关的API函数,但不知如何在BCB中加入想用的相关函数.望高手指教.谢谢!
取本机的:Now()
取服务器SQL:select getdate() as Rtime
NOW()怎么用?谢谢
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime t=Now();
ShowMessage(t);
}
GetSystemTime
The GetSystemTime function retrieves the current system date and time. The system time is expressed in Coordinated Universal Time (UTC).
VOID GetSystemTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);
Parameters
lpSystemTime
Pointer to a SYSTEMTIME structure to receive the current system date and time.
ShowMessage(DateToStr(Now()));
TDateTime t=Now();
ShowMessage(t.DateString());
ShowMessage(t.DateTimeString());
这样的函数一般都能在time.h下找得到
SYSTEMTIME time
GetLocalTime(&time);
FormatDateTime( "dddd,mmmm,d,yyyy,hh:mm AM/PM ",Now());
TDateTime t=Now();
t.DateString()); 日期
t.DateTimeString()); 时间
这个很好..
TDateTime t=Now();
t.DateString()); 日期
t.DateTimeString()); 时间
JF
TDateTime dt = Now();
AnsiString st = dt.FormatString( "YYYYY-MM-DD HH:NN:SS ");
ShowMessage(st);
TDataTime GetDate;
AnsiString thisTime = GetDate.CurrentDateTime().Format( "yyyy-mm-dd ");
哪在API中获得系统函数是什么呢? 另外SYSTEMTIME结构是用来存放时间的吗?
哪在API中获得系统函数是什么呢? 另外SYSTEMTIME结构是用来存放时间的吗?
SYSTEMTIME time
GetLocalTime(&time);
是的,查帮助!
哦 那么这么写可以么?
…
SYSTEMTIME time;
……
MessageBox(hwnd,time.wYear, "time ",NULL);
time.wYear是WORD类型的 参数是CHAR类型 那么 把WORD类型转为CHAR 然后再用MessageBox() 可以实现吗?
AnsiString sss;
YMD= new SYSTEMTIME;
GetLocalTime(YMD);
sss= String(YMD-> wYear)+String( "- ")+String(YMD-> wMonth)+String( "- ")+String(YMD-> wDay) ;
然后你读字符串SSS的值就行了。
我在给公司用C++ Builder做的数据库中调试通过了,
XP,2000都可以的。
也不用加其他的头文件。调用的是WINDOWS系统的咚咚。
我在VC6.0中 提示 AnsiString 没定义~
我在VC6.0中 提示 AnsiString 没定义~
…….
VC请用CString
Borland C++ builder请用AnsiString
如果你希望程序那里都可用
请用char *pCh = "time ";
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "resource.h "
还是没定义
没有 CString 这个类 错误是 没有定义
进展的一点是 GetLocalTime(&systime); 可以获取系统时间
但是SYSTEMTIME 结构里变量是WORD 如果用MessageBox()显示出来的话 要把WORD转换成char型 现在问题就是转换了~ 偶不知道 高手多多指教哦~
也许是我记忆错误吧?
Cstring应该是有的…..
这几天休息的时候看完了一本小人书
里面有这么一段 我送给楼主
天才和高手到底有什么区别呢?
天才在错误发生之前可能会预见
高手呢?
高手则是在不断的调错排错中慢慢长大的
TDateTime t=Now();
t.DateString()); 日期
t.DateTimeString()); 时间
楼上的是用的MFC中的类~~ CSTRING 也是MFC中的 我只想知道 API里怎么把WORD类型转换为char类型~
大家在这里讨论也是一个交流的过程, 我并没有等着大家来解决,在这同时,我一直努力着~
另外 其实这个问题已经用另一个方法解决了 我想多学点东西 想问下 这个类型转换 是否能转~~
下面是实现代码
SetTextColor(hdc,RGB(0,255,0));
SetBkColor(hdc,RGB(0,0,0));
SetBkMode(hdc,OPAQUE);
sprintf(buffer, "Today is =( %d , %d ) ",systime.wYear,systime.wDay);
TextOut(hdc,0,75,buffer,strlen(buffer));
嘎嘎 貌似搞错达~~
取本机的:Now()
取服务器SQL:select getdate() as Rtime
包含Windows.h头文件即可!VC,BCB,Linux下通用。
//取系统时间
void XGetSystemDateTime(XSystemDateTime_s & s)
{
#if CONFIG_VC || CONFIG_BCB
SYSTEMTIME st;
GetSystemTime(&st);
s.Year = st.wYear;
s.Month = st.wMonth;
s.Day = st.wDay;
s.WeekDay = st.wDayOfWeek;
s.Hour = st.wHour;
s.Minute = st.wMinute;
s.Second = st.wSecond;
s.Milliseconds = st.wMilliseconds;
s.Zone = -480; //默认时区为东八区
TIME_ZONE_INFORMATION tz;
if(GetTimeZoneInformation(&tz) == TIME_ZONE_ID_STANDARD )
{
s.Zone = (XShort)tz.StandardBias;
}
#elif CONFIG_GCC
//throw XException( "在GCC下暂未实现 ");
struct timeval tv;
struct timezone tza;
gettimeofday(&tv,&tza);
s.Milliseconds = tv.tv_usec / 1000;
XInt tmp = tv.tv_sec;
s.Second = tmp % 60;
tmp /= 60;
s.Minute = tmp % 60;
tmp /= 60;
s.Hour = tmp % 24;
tmp /= 24;
tmp += DAYS_1970_1_1;
XInt iYear,iMonth,iDay;
DaysToDate(tmp,iYear,iMonth,iDay);
s.Year = iYear;
s.Month = iMonth;
s.Day = iDay;
s.WeekDay = tmp % 7;
s.Zone = tza.tz_minuteswest;
#else
throw XException( "未知编译器 ");
#endif
}
路过..标记.
//时间日期全有,写在TIMER里还可以动的,秒钟都能显示。
SYSTEMTIME *GTL =new SYSTEMTIME;
GetLocalTime(GTL);
lbldate-> Caption=String(GTL-> wYear)+ '- '+String(GTL-> wMonth)+ '- '+String(GTL-> wDay);
lbltime-> Caption=String(GTL-> wHour)+ ': '+String(GTL-> wMinute)+ ': '+String(GTL-> wSecond);
String Week[7]={ "星期日 ", "星期一 ", "星期二 ", "星期三 ", "星期四 ", "星期五 ", "星期六 "};
lblday-> Caption=Week[GTL-> wDayOfWeek];
该回复于2008-07-10 02:46:45被版主删除
15 Jul
我想得到某个窗口的内容,并回显.如得到记事本窗口的内容,我应该使用哪个函数呢?最好有个例子!谢谢!
AnsiString calc="calc.exe";
ShellExecute(Handle,"Open",calc.c_str (),0,0,SW_SHOW);
HWND hwParent=FindWindow(NULL,"计算器");//获得主窗体句柄
HWND hwChild=FindWindowEx(hwParent,NULL,"Static",NULL);
LPTSTR text;
GetWindowText(hwChild,text,255);
Edit1->Text=text;
http://www.ttadd.com/diannao/HTML/146807.html
GetDlgItemText
7 Jul
请问:C++builder怎么得到可执行文件所在的目录?
我在程序中GetCurrentDir()得到当前目录,但是存在一个严重问题:
CurrentDir与exe文件所在的目录不完全等同。
调用OpenDialog后,GetCurrentDir()得到的目录就不一定是exe文件所在的目录了。
ExtractFileDir(Application->ExeName)
哈哈,没抢到!
多谢两位。
ExtractFileDir(Application->ExeName); // 带 \
ExtractFilePath(Application->ExeName); // 不带 \
ExtractFileName(Application->ExeName); // 获取运行程序名称
手头上有个程序,用的是borland写的,有个TMGrid类,我现在想通过sendmessage取出TMGrid的行,列,应该怎么弄?
试过用lvm类的message,好像不行。
没有头文件啊。只有一个单独的程序。
文件大不大?不大传上来如何?
文件不大,但是需要连上设备,没有设备不能运行
我用OllyICE看了一下,好像是TStringGrid继承过来的。
0040E537 ¦. E8 D83E0400 call <jmp.&VCL50.Grids::TStringGrid::SetCells>
以前的代码找不到了. 只记得大概了.
先获得TMGrid的Handle, 然后通过发送 RM_GetObjectInstance 消息, 然后把转换了TStringGrid 直接读取行,列的值. 还用到了一个EnumProps.
当时是取DBGrid中的数据, D7,BCB6 写的程序肯定没有问题. 其它的未测试.
好像没那么简单,呵呵.
30 Jun
通常如果已知一个窗体的名称,可以用Findwindow找到窗体句柄,再用Getwindows遍历窗体上控件,找到控件句柄.
这只是理想状态,有时弹出模式对话框根本就没有标题,从SPY++上就可以看出有很多是这种情况.我从SPY++上也看到可以通过进程的句柄,或线程的句柄下找到这些控件,网上多是遍历进程 和线程的文章,我已找到了进程或线程的句柄,如何遍历这进程或线程下的控件找到我需要的控件的句柄,一直没有成功,急请各位大侠指点.顿足拜谢.
注:所找到的进程是别的程序创建的,我不知代码的.
<img src="c:\u1.jpg" alt="0" />
枚举线程的窗口
EnumThreadWindows
我已找到了所有的进程,没有必要再枚举进程得到进程的名字了.我需要的是进程下各控件的句柄
这个就不怎么懂了,帮顶下吧,
等待结果~~~
<img src="c:\u1.jpg" alt="0" />
file:///d:/sss.jpg
比较汗….
我已枚举出了线程的窗口,得到的是线程的句柄,再往下如何得到线程下所有控件的句柄列表就不行了.
有一篇文章是用EnumThreadWindows 获得线程句柄的例子,我添附在下面.这个例子是用VB写的,我把它拷到VB
里面,实际运行了一下,得不到线程下控件列表的句柄.您可以试试.
我现在在想别的办法:遍历所有标题为空的对话框,再从对话框中查找所需要的控件(条件是这个控件的标题在内存中是唯一的),如果找到的话,再找其父窗口的句柄来发消息.目前在试写中.成功以后贴上与大家共享.
如何得到线程下所有控件的列表,应用何函数?能否说得说细一点或贴上代码让大伙瞄瞄.已经搞了三天了,实在走投无路了万分焦急.
添附:
如何使用 WIN32 API 枚举窗口
1.在 Visual Basic 中启动一个新的项目。默认情况下创建 Form1。
2.添加两个 CommandButtons 和一个 TextBox。
3.将下面的代码复制到该窗体的模块中: Option Explicit
Private Sub Command1_Click()
Dim lRet As Long, lParam As Long
Dim lhWnd As Long
lhWnd = Me.hwnd ' Find the Form's Child Windows
' Comment the line above and uncomment the line below to
' enumerate Windows for the DeskTop rather than for the Form
'lhWnd = GetDesktopWindow() ' Find the Desktop's Child Windows
' enumerate the list
lRet = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
End Sub
Private Sub Command2_Click()
Dim lRet As Long
Dim lParam As Long
'enumerate the list
lRet = EnumWindows(AddressOf EnumWinProc, lParam)
' How many Windows did we find?
Debug.Print TopCount; " Total Top level Windows"
Debug.Print ChildCount; " Total Child Windows"
Debug.Print ThreadCount; " Total Thread Windows"
Debug.Print "For a grand total of "; TopCount + _
ChildCount + ThreadCount; " Windows!"
End Sub
4.添加包含以下代码的模块: Option Explicit
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
lpRect As RECT) As Long
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId _
As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hwnd As Long, ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long
Public TopCount As Integer ' Number of Top level Windows
Public ChildCount As Integer ' Number of Child Windows
Public ThreadCount As Integer ' Number of Thread Windows
Function EnumWinProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long, ProcessID As Long, ThreadID As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
TopCount = TopCount + 1
' see the Windows Class and Title for each top level Window
Debug.Print "Top level Class = "; WinClass; ", Title = "; WinTitle
' Usually either enumerate Child or Thread Windows, not both.
' In this example, EnumThreadWindows may produce a very long list!
RetVal = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
ThreadID = GetWindowThreadProcessId(lhWnd, ProcessID)
RetVal = EnumThreadWindows(ThreadID, AddressOf EnumThreadProc, _
lParam)
EnumWinProc = True
End Function
Function EnumChildProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
Dim WinRect As RECT
Dim WinWidth As Long, WinHeight As Long
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ChildCount = ChildCount + 1
' see the Windows Class and Title for each Child Window enumerated
Debug.Print " Child Class = "; WinClass; ", Title = "; WinTitle
' You can find any type of Window by searching for its WinClass
If WinClass = "ThunderTextBox" Then ' TextBox Window
RetVal = GetWindowRect(lhWnd, WinRect) ' get current size
WinWidth = WinRect.Right - WinRect.Left ' keep current width
WinHeight = (WinRect.Bottom - WinRect.Top) * 2 ' double height
RetVal = MoveWindow(lhWnd, 0, 0, WinWidth, WinHeight, True)
EnumChildProc = False
Else
EnumChildProc = True
End If
End Function
Function EnumThreadProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ThreadCount = ThreadCount + 1
' see the Windows Class and Title for top level Window
Debug.Print "Thread Window Class = "; WinClass; ", Title = "; _
WinTitle
EnumThreadProc = True
End Function
Public Function StripNulls(OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
5.运行项目并单击 Command1。这将枚举出该窗体的子窗口直至找到 TextBox,然后将 TextBox
的高度扩大一倍并将其移动到位置 (0, 0)(该窗体的左上方。)
6.单击
Command2。这会立即在即时窗口中列出所有顶级窗口及其子窗口以及与其线程关联的任何非子窗口的类和标题(如果存在)。请注意,这可以是一个非常长的列表,可能需要一段时间才能列出所有内容。
7.从“运行”菜单选择“结束”或单击“结束”按钮以停止程序。根据注释更改 Sub Command1_Click 中的代码以传递来自
GetDesktopWindow 的句柄。运行项目并单击 Command1 以枚举 DeskTop
的所有子窗口。请注意,完成此过程需要花费一些时间。
先把图片传到晚上,然后点编辑框上面的插入图片就可以了。
控件也是有窗口的,枚举窗口为什么不能枚举的控件的?
咳,不知道是不是我理解错了,EnumThreadWindows列举的是窗口句柄而不是线程句柄!
下面是用EnumThreadWindows列举出本线程所有窗口的例子(所有窗口的标题放在Form1的Memo1里),如果楼主还要找这些窗口里的子控件,可以再用FindWindowEx或EnumChildWindows之类的方法找。
BOOL CALLBACK EnumThreadWndProc( HWND hwnd, LPARAM lParam ) { char buf[100]={0}; ::SendMessage(hwnd,WM_GETTEXT,100,(WPARAM)buf); // 这里的hwnd就是EnumThreadWindows找到的窗口HWND ((TMemo*)lParam)->Lines->Add(buf); return TRUE; } void __fastcall TForm1::Button1Click(TObject *Sender) { EnumThreadWindows( GetCurrentThreadId() ,(WNDENUMPROC)EnumThreadWndProc, LPARAM(Memo1)); } //—————————————————————————
这里控件是放在一个模式对话框里,标题栏是空的字符串,表面上看到的标题栏是一个Edit控件.而系统中存在大量"#32770"的对话框,它们的标题也各种各样,很可能就有空字符串,而它返回的是找到的第一个窗口的句柄,不能保证一定是你需要的.所以较为可行的方法是枚举系统当前的所有进程,从中查找模块名为您需要的进程,从进程中查找属于控件的句柄.
现在网上枚举窗口的方法绝大多数都是从一个对话框里找它上面控件的句柄,我因为这个对话框的句柄找不到,才想用进程或线程里找.
你把SPY++打开,调到查看线程或进程里,可以看到线程下面控件名及句柄.我想知道它是怎么出来的.
请告诉我传图片的方法,我上传一张图片给您瞧瞧
引用 10 楼 loveshell 的回复:]
先把图片传到晚上,然后点编辑框上面的插入图片就可以了。
控件也是有窗口的,枚举窗口为什么不能枚举的控件的?
[/Quote]
凭印象写的,没调试过。。。
HANDLE GetMyHandle(HANDLE hParant)// 参数为父句柄 { const int nBufLen = 256; char cTemp[nBufLen]; HANDLE hTemp; hTemp = GetWindow(hParant,GW_CHILD);//获得进程下的第一个子句柄 while(hTemp) { memset(cTemp,0,nBufLen); GetWindowText(hTemp,cTemp,nBufLen); if (AnsiString(cTemp) == "AfxFrameOrView42") return hTemp;// 若是要找的句柄则返回 hTemp = GetWindow(hTemp,GW_HWNDNEXT); } return NULL; }
谢谢指点.但我认为进程下面的子句柄是线程,线程下面才是控件,从13楼我贴出的图片上可以看出.
画有二个齿轮的是进程,一个齿轮的是线程,再下面是各控件.可能你的办法也只能找到线程了.
我原也想这么干,我认为对话框是控件的容器,所以能用GetWindow(hParant,GW_CHILD)方法找,线程与控件可能不存在这个关系,所以能否用这个函数找我不敢确定.
昨天通过努力我用下列办法写的代码:
遍历所有标题为空的对话框,再从对话框中查找所需要的控件(条件是这个控件的标题在内存中是唯一的)
调试后虽然还有BUG,但一般情况下可以找到所需的控件句柄,有时找的不大对或找不到.但不是通过线程与进程来找的,故与我本意有差别,供参考指正
HWND TForm1::FindPressmeBtnHandleProcess()
{
HWND h_WindowHandle= FindWindow("#32770",""); //Empty caption Dialogbox handle
HWND h_ControHandle; //Control handle
char cFindControCaption[128];
char Searchnt[128];
char cFindClassName[128];
while(h_WindowHandle)
{
sPush(h_WindowHandle);
GetcFindClassName(h_WindowHandle,cFindClassName,128);
SendMessage(h_WindowHandle,WM_GETTEXT,128,(LPARAM)Searchnt);
if (AnsiString(cFindClassName)== "#32770" && AnsiString( Searchnt)=="")
{
h_ControHandle=GetWindow(h_WindowHandle,GW_CHILD);
while(1)
{
SendMessage(h_ControHandle,WM_GETTEXT,128,(LPARAM)FindControCaption);
GetcFindClassName(h_ControHandle,cFindClassName,128);
if (AnsiString(cFindControCaption)=="Press me" && AnsiString(FindClassName)== "Button" )
{
//Find the handle and stop the loop
return h_ControHandle ;
}
else
{
sPush(h_ControHandle);
h_ControHandle=GetWindow(h_ControHandle,GW_HWNDNEXT);
if(!h_ControHandle)
{
while (!h_ControHandle && stack_Top>0)
{
h_ControHandle=sPop();
h_ControHandle=GetWindow(h_ControHandle,GW_CHILD);
}
if(stack_Top== 0)break;
}
}
} // while(1) end
break;
}
else
{
h_WindowHandle=GetWindow(h_WindowHandle,GW_HWNDNEXT);
}
}
}
关注着。。。。
不怎么懂这方面的。。
Q:我想枚举一个进程(自己写的应用程序)中的所有句柄,包括线程,资源,文件等等。有什么好方法吗?
传说中的NtQuerySystemInformation可以吗。
A: NtQuerySystemInformation价格便宜量又足,我们一直用它
#include <windows.h>
#include <winternl.h>
//#pragma warning(disable:4786)
//#pragma warning(disable:4244)
#include <hash_map>
#include <hash_set>
#include <iostream>
using namespace std;
using namespace stdext;
hash_set <UINT32> g_HandleList;
hash_map <UINT32, UINT32> hadle_map;
typedef pair <UINT32, UINT32> hadle_Pair;
typedef UNICODE_STRING OBJECT_NAME_INFORMATION;
typedef UNICODE_STRING *POBJECT_NAME_INFORMATION;
#define ObjectNameInformation 1
#define SystemHandleInformation 0×10 // Information Class 16
#define STATUS_SUCCESS ((NTSTATUS)0×00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0×80000005L)
typedef struct _SYSTEM_HANDLE_ENTRY {
ULONG OwnerPid;
BYTE ObjectType;
BYTE HandleFlags;
USHORT HandleValue;
PVOID ObjectPointer;
ULONG AccessMask;
} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY;
typedef struct _SYSTEM_HANDLE_INFORMATION{
ULONG Count;
SYSTEM_HANDLE_ENTRY Handle[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
#define CURRENT_PROCESS_HANDLE_MAX 102400
SYSTEM_HANDLE_ENTRY StructHandleList[CURRENT_PROCESS_HANDLE_MAX]; //all handle save
enum {
OB_TYPE_UNKNOWN = 0,
OB_TYPE_TYPE = 1,
OB_TYPE_DIRECTORY,
OB_TYPE_SYMBOLIC_LINK,
OB_TYPE_TOKEN,
OB_TYPE_PROCESS,
OB_TYPE_THREAD,
OB_TYPE_UNKNOWN_7,
OB_TYPE_EVENT,
OB_TYPE_EVENT_PAIR,
OB_TYPE_MUTANT,
OB_TYPE_UNKNOWN_11,
OB_TYPE_SEMAPHORE,
OB_TYPE_TIMER,
OB_TYPE_PROFILE,
OB_TYPE_WINDOW_STATION,
OB_TYPE_DESKTOP,
OB_TYPE_SECTION,
OB_TYPE_KEY,
OB_TYPE_PORT,
OB_TYPE_WAITABLE_PORT,
OB_TYPE_UNKNOWN_21,
OB_TYPE_UNKNOWN_22,
OB_TYPE_UNKNOWN_23,
OB_TYPE_UNKNOWN_24,
OB_TYPE_CONTROLLER,
OB_TYPE_DEVICE,
OB_TYPE_DRIVER,
OB_TYPE_IO_COMPLETION,
OB_TYPE_FILE
} SystemHandleType;
//NtQuerySystemInformation
typedef DWORD (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
//NtQueryObject
typedef DWORD (WINAPI *tNTQO)(HANDLE ObjectHandle, DWORD ObjectInformationClass, PVOID ObjectInformation, DWORD Length, PDWORD ResultLength);
//NtDeviceIoControlFile
typedef DWORD (WINAPI *tNTDIOCF)(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, DWORD IoControlCode, PVOID InputBuffer, DWORD InputBufferLength, PVOID OutputBuffer, DWORD OutputBufferLength);
void EnableDebugPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tokenPriv;
LUID luidDebug;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)!= FALSE)
{
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
{
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luidDebug;
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL,NULL);
}
}
}
LPWSTR GetObjectName(HANDLE hObject)
{
LPWSTR lpwsReturn = NULL;
tNTQO pNTQO = (tNTQO)GetProcAddress(GetModuleHandle("NTDLL.DLL"),"NtQueryObject");
if (pNTQO != NULL)
{
DWORD dwSize = 200* sizeof(OBJECT_NAME_INFORMATION);
POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION)new BYTE[dwSize];
NTSTATUS ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
if (ntReturn == STATUS_BUFFER_OVERFLOW)
{
delete pObjectInfo;
pObjectInfo = (POBJECT_NAME_INFORMATION)new BYTE[dwSize];
ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize,&dwSize);
}
if ((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL))
{
lpwsReturn = (LPWSTR)new BYTE[pObjectInfo->Length + sizeof(WCHAR)];
ZeroMemory(lpwsReturn, pObjectInfo->Length + sizeof(WCHAR));
CopyMemory(lpwsReturn, pObjectInfo->Buffer, pObjectInfo->Length);
}
delete pObjectInfo;
}
return lpwsReturn;
}
DWORD GetProcHandle(PSYSTEM_HANDLE_INFORMATION StructHandle,DWORD pid)
{
//1 init
DWORD re = STATUS_INFO_LENGTH_MISMATCH;
DWORD Count =0;
DWORD i, nedCount = 0, j = 0;
HINSTANCE NtdllDll = NULL;
// pid= GetCurrentProcessId();
//2 get system path and ntdll.dll
char mSystemPath[MAX_PATH+1];
memset(mSystemPath,0×00,MAX_PATH+1);
GetSystemDirectory(mSystemPath,MAX_PATH);
strcat(mSystemPath,"\\ntdll.dll");
NtdllDll = GetModuleHandle(mSystemPath);//LoadLibrary("ntdll.dll");
if(NtdllDll == NULL)
{
return 0;
}
//3 get func NtQuerySystemInformation
PROCNTQSI NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(NtdllDll,"NtQuerySystemInformation");
if (NtQuerySystemInformation == NULL)
{
return 0;
}
//4 get system handle list
DWORD dwSize = sizeof(SYSTEM_HANDLE_INFORMATION);
PSYSTEM_HANDLE_INFORMATION pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
NTSTATUS ntReturn = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
//4.1 get all system handle count
if (ntReturn == STATUS_INFO_LENGTH_MISMATCH)
{
delete pHandleInfo;
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)new BYTE[dwSize];
ntReturn = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
}
//4.2 Enumerate all system handles
EnableDebugPrivilege();
//PrintProcessNameAndID(pid);
if (ntReturn == STATUS_SUCCESS)
{
for (DWORD dwIdx = 0; dwIdx <pHandleInfo->Count; dwIdx++)
{
//if (pHandleInfo->Handle[dwIdx].OwnerPid == pid)
{
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE ¦ PROCESS_QUERY_INFORMATION ¦ PROCESS_VM_READ, FALSE, pHandleInfo->Handle[dwIdx].OwnerPid);
if (hProcess != INVALID_HANDLE_VALUE)
{
HANDLE hObject = NULL;
if (DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handle[dwIdx].HandleValue, GetCurrentProcess(), &hObject,STANDARD_RIGHTS_REQUIRED, FALSE, 0) != FALSE)
{
LPWSTR lpwsName = GetObjectName(hObject);
if (lpwsName != NULL)
{
wprintf(L"\nobject Name:\t%s ,object type:\t%d",lpwsName, pHandleInfo->Handle[dwIdx].ObjectType);
delete lpwsName;
}
CloseHandle(hObject);
}
LPWSTR lpwsName = GetObjectName((HANDLE)pHandleInfo->Handle[dwIdx].HandleValue);
if (lpwsName != NULL)
{
wprintf(L"\nobject Name:\t%s ,object type:\t%d",lpwsName, pHandleInfo->Handle[dwIdx].ObjectType);
delete lpwsName;
}
CloseHandle(hProcess);
}
nedCount++;
}
}
delete pHandleInfo;
}
return nedCount;
}
vc的代码,要改到bc的.
需要一些功力的.呵呵:)
我在vc下通过的,bc恩, 你就自己加油哈.
DWORD pID;
PROCESSENTRY32 lppe;
HANDLE hSnapshot;
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
lppe.dwSize = sizeof(lppe);
rValue=Process32First(hSnapshot,&lppe);
while(rValue)
{
if (ExtractFileName(lppe.szExeFile).LowerCase()=="watch.exe")//此处最好用字符串判等
{
pID=lppe.th32ProcessID; //在此便得到了进程的ID
break;
}
rValue=Process32Next(hSnapshot,&lppe);
}
HANDLE pHandle=OpenProcess(PROCESS_ALL_ACCESS,false,pID);
if(!pHandle)
ShellExecute(NULL,NULL,"d:\\watch\\watch.exe",NULL,"d:\\watch",SW_SHOW);
CloseHandle(hSnapshot);
*/
bool rValue;
DWORD pID;
PROCESSENTRY32 lppe;
HANDLE hSnapshot;
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
lppe.dwSize = sizeof(lppe);
rValue=Process32First(hSnapshot,&lppe);
for(pID=0; rValue; )
{
if (ExtractFileName(lppe.szExeFile).LowerCase()=="watch.exe")
{
pID=lppe.th32ProcessID; //在此便得到了进程的ID
break;
}
rValue=Process32Next(hSnapshot,&lppe);
}
CloseHandle(hSnapshot);
if (pID==0)
{
rec->Add("Run Watch.exe at Time:"+Now().DateTimeString());
rec->SaveToFile("record.txt");
ShellExecute(NULL,NULL,"d:\\watch\\watch.exe",NULL,"d:\\watch",SW_SHOW);
}
DWORD pID;
PROCESSENTRY32 lppe;
HANDLE hSnapshot;
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
lppe.dwSize = sizeof(lppe);
rValue=Process32First(hSnapshot,&lppe);
while(rValue)
{
if (ExtractFileName(lppe.szExeFile).LowerCase()=="watch.exe")//此处最好用字符串判等
{
pID=lppe.th32ProcessID; //在此便得到了进程的ID
break;
}
rValue=Process32Next(hSnapshot,&lppe);
}
HANDLE pHandle=OpenProcess(PROCESS_ALL_ACCESS,false,pID);
if(!pHandle)
ShellExecute(NULL,NULL,"d:\\watch\\watch.exe",NULL,"d:\\watch",SW_SHOW);
CloseHandle(hSnapshot);
*/
bool rValue;
DWORD pID;
PROCESSENTRY32 lppe;
HANDLE hSnapshot;
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
lppe.dwSize = sizeof(lppe);
rValue=Process32First(hSnapshot,&lppe);
for(pID=0; rValue; )
{
if (ExtractFileName(lppe.szExeFile).LowerCase()=="watch.exe")
{
pID=lppe.th32ProcessID; //在此便得到了进程的ID
break;
}
rValue=Process32Next(hSnapshot,&lppe);
}
CloseHandle(hSnapshot);
if (pID==0)
{
rec->Add("Run Watch.exe at Time:"+Now().DateTimeString());
rec->SaveToFile("record.txt");
ShellExecute(NULL,NULL,"d:\\watch\\watch.exe",NULL,"d:\\watch",SW_SHOW);
}
去试试看看。。呵呵。。
可能以后会用到~~
进程就像一个目录,而线程则是这个目录下子目录,要遍历一个进程下所有句柄,就像遍历一个目录所以文件一样。
因此,可以用递归得到进程下所有句柄,不过只有进程和线程的话,再套一层while就行了。
控件的话,我觉得可以试着用FindWindowEx来查找句柄
请大家别把这个问题看得太简单了,我认为无论是进程快照还是GetWindow都较难实现,因为我已各种方法试验过多次了.我认为19楼的办法是正解.Native API是微软不公开的底层API,功能非常强大.,不仅仅能查看系统进程,包括其他进程线程信息,内存页表信息,io读写信息,CPU缓存信息,Native api 都位于NTDLL.DLL中,是用户层最底层的逻辑实现方式.
遗憾的是到现在还没有调试出来,还得努力学习提高.
28 Jun
ADOQUERY ACCESS 怎么才能得到数据库里的所有表的名字?我想放到LISTBOX里面。请高手赐代码?说的详细些啊。我是初学者。
ADOQUERY 貌似没法实现,顶老蔡!
先顶下菜锅
TADODataSet *pDataSet=new TADODataSet(0); //OpenSchema参数比较多,这里我们只要获取他的表,你还可以获取很多东东 ADOConnection1->OpenSchema(siTables,Variant::NoParam(),Variant::NoParam(),pDataSet); try { //将结果加入ListBox中 pDataSet->First(); while(!pDataSet->Eof) { //只获取用户创建的表 if(pDataSet->FieldByName("TABLE_TYPE")->AsString.UpperCase()=="TABLE") ListBox1->Items->Add(pDataSet->FieldByName("TABLE_NAME")->AsString); pDataSet->Next(); //指针移动到下一条记录 } } catch(…) { MessageBox(0,"bcb群-[4670-3864]","发生不可预知的错误!",MB_OK); }
建议用老蔡的方法!,若要获取数据库更多的信息(比如每个表的所有字段等),可以用这个方法
结账先..谢谢楼上的几位啦.