《分析 100 个 AU3 内置函数的内部原理,与其所调用的 API 函数》
ACN官方书籍即将面世
你没有看错。
想想现在的自己应该做些事情了,即便家人不给我压力,我自己也会觉得不自在。三年前我在【谈天说地】版块发了那个“想写本书”的帖子,现在回顾那个帖子,觉得其中只有一句话是现在的我所认同的,那就是“时间和精力多得是,目前缺少的是技术与学识”。如今三年已经过去,书完成的进度还是那么两页。这三年在编程方面又成长了很多,在 2012 年的某段时期,我有四五个月的时间不能上网,也因此将以往泡在贴吧里和看动漫的时间都用在了钻研编程上,也正是因为如此,我觉得在那几个月中,自己仿佛学到了 原本需要一两年才能全部掌握的知识,感觉那几个月过得飞快。
《分析 100 个 AU3 内置函数的内部原理,与其所调用的 API 函数》,这个想法已在我心中酝酿多日,早晚是要说出来的,我想这个想法相较于三年前的那个想法,还是这个比较现实一些。我的设想是这样的,请诸位帮我参谋一下是否可行,欢迎给我泼冷水。
分析 100 个 AU3 内置函数的内部原理,与其所调用的 API 函数,当然不是在秀代码,否则就失去了书籍的意义,因为大可直接调用这些内置函数。
有很多 AU3 的学习者已入门 AU3,并已熟练掌握了只与 AU3 有关的那部分函数的用法,之后再想进步,却发现遇到了瓶颈,原因只有一个,那就是不会用 DllCall 函数调用操作系统提供的 API 以满足更多复杂的应用。书籍将站在这些人的角度,将这 100 个内置函数所使用的 API 用 AU3 的 DllCall 函数一一调用,并注有详细分析,一来可以了解 AU3 解析器在内部是如何工作的,二来可以学习 API 的调用方法。
例如内置函数 MsgBox,其实质是调用了 User32.dll 中的 MessageBoxW 函数,而 MessageBoxW 函数又调用了相同模块中的 MessageBoxExW 函数,MessageBoxExW 接着又调用 MessageBoxTimeoutW 函数,最后由 MessageBoxTimeoutW 完成实质的操作。书籍中只会分析 MessageBoxW,抑或分析 分处于这条调用链上的每个 API 函数,视读者的要求而定。另外,可以注意到,MessageBoxTimeoutW 这个函数是带有超时功能的,而 MessageBoxW 则不然,但是 MsgBox 的参数中,确实有一个“超时”参数,这就说明 AU3 解析器在内部 自己维护了一个计时器,等时间一到,就自己关闭对话框, AU3 的作者也许不知 MessageBoxTimeoutW 函数的原型,果真在 MSDN 中没有找到这个函数,否则作者不会不惜浪费成本调用 MessageBoxW 函数——如此之分析,分析到何种程度,都要视读者的要求和自己的知识而定。
书籍卖的不是代码,而是一种学习的思路和方法,相信看完这 100 个内置函数的内部流程,以及它们所调用的那些不止 100 个 API 函数的分析以后,在遇到陌生的 API,或编写一些高级应用时,也会知道应该调用哪些 API 以及它们的调用方法了,如此一来,如果人人都能随心所欲地通过调用 API 来拓展 AU3 的功能,那么我三年前的那个想法就要付诸东流了。
以上。欢迎拍砖。 哇前排留名必火 前排,火钳留名! 确实,其实最大的瓶颈就是API。我觉得这个思路可行,只要行文理字浅显一些,或者说一开始浅显一些,会是一本很不错的教材~
另外,给P大一个小建议,是否可行不敢下结论。现在的中文API资料实在太少了,已有的书籍也非常陈旧,P大出完这本《分析 100 个 AU3 内置函数的内部原理,与其所调用的 API 函数》后,可以考虑尝试出一本API翻译类的书,任何WINDOWS下的编程语言都能适用~ 回复 4# xiaowo
感谢 xiaowo 兄的建议。这是后话了,有没有那个学识还不好说。
“行文理字浅显一些”,其实我最担心的就是这个,就是怕最后写出来只有自己看得懂。 xiaowo 兄觉得顶楼那段关于 MsgBox 的分析够得上是浅显易懂的吗?我好有个底~ - -|||
///////////////////////////////////////////////////////////////////////////////
// Util_MessageBoxEx()
//
// Windows message box with an optional timeout (0=wait forever)
///////////////////////////////////////////////////////////////////////////////
int Util_MessageBoxEx(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, UINT uTimeout)
{
MsgBoxExData MyData;
unsigned int uThreadID;
HANDLE hThreadHandle = NULL;
// Reset the timed out flag
g_bMsgBoxTimedOut = false;
if (uTimeout)
{
g_bMsgBoxThreadEnabled = true;
MyData.CurrentThreadID = GetCurrentThreadId();
MyData.dwTimeout = (DWORD)uTimeout;
hThreadHandle = (HANDLE)_beginthreadex(NULL, 0, Util_TimeoutMsgBoxThread, (void*)&MyData, 0, &uThreadID);
}
// Run the windows message box - the spawned thread will force it to close if it times out
int Res = MessageBox(hWnd, lpText, lpCaption, uType);
if (hThreadHandle)
{
g_bMsgBoxThreadEnabled = false; // Signal thread to terminate (if not already)
WaitForSingleObject(hThreadHandle, INFINITE);
CloseHandle(hThreadHandle);
}
if (g_bMsgBoxTimedOut == true)
return -1; // Timed out
else
return Res;
}
unsigned int _stdcall Util_TimeoutMsgBoxThread(void *pParam)
{
MsgBoxExData *pMyData = (MsgBoxExData *)pParam;
DWORD dwStart, dwDiff, dwCur;
// Get the current time, and close the message box after the timeout has been
// exceeded - check every 10ms to avoid CPU load
dwStart = timeGetTime();
for (;;)
{
if (g_bMsgBoxThreadEnabled == false)
return 0; // Caller requested close
// Get current time in ms
dwCur = timeGetTime();
if (dwCur < dwStart)
dwDiff = (UINT_MAX - dwStart) + dwCur; // timer wraps at 2^32
else
dwDiff = dwCur - dwStart;
// Timer elapsed?
if (dwDiff >= pMyData->dwTimeout)
break;
else
Sleep(10);
}
// Find and close the msgbox
g_hwndMsgBox = NULL;
EnumThreadWindows(pMyData->CurrentThreadID, Util_FindMsgBoxProc, 0);
if (g_hwndMsgBox == NULL)
return 0; // MsgBox doesn't exist, just exit
// Signal the timeout
g_bMsgBoxTimedOut = true;
// End the MessageBox with our special message
EndDialog(g_hwndMsgBox, 1); // Id 1 works no matter what buttons are used
return 0;
}
BOOL CALLBACK Util_FindMsgBoxProc(HWND hwnd, LPARAM lParam)
{
TCHAR szClassname;
BOOL RetVal = TRUE;
int nRes = GetClassName(hwnd, szClassname, 256);
if (!_tcscmp(szClassname, TEXT("#32770")) ) // Class name for a MessageBox window
{
g_hwndMsgBox = hwnd;
RetVal = FALSE;
}
return RetVal;
}
很多东西都是各取所需,完成这种工作更多对自己的提升要大过看书的人。 快出…………………… 留名待查,P版好久不见 回复 6# thesnow
感谢 thesnow 兄捧场,这段代码是哪里的? 回复thesnow
感谢 thesnow 兄捧场,这段代码是哪里的?
pusofalse 发表于 2013-3-4 09:32 http://www.autoitx.com/images/common/back.gif
from autoit,all version. 很想了解一下这些内部原理。 回复 5# pusofalse
现在的我能够理解,不过如果是换在几个月前,确实是无法理解的。可能P大还要费些心思在一开始的时候把读者带入你的行文习惯中,这样后面再看到同样的描述就不会生涩了。
打个不知道恰不恰当的比方:老师上课要造一个句子,为生动一些需要用到一个成语,但老师不确定这个成语是不是所有的学生都知道。于是她先教学生这个成语,然后再造句,学生不但学到了成语,也更生动地学习了句子。下次老师造句时再用到了这个成语,学生也完全能够接受了。 不管如何,这样的书写出来必定有益 哇前排留名必火