发现一个文件上传的好网站
http://www.uploadmirrors.com/
这个网站不错,以后可以将一些源代码传上去share
2009年4月21日星期二
2009年4月13日星期一
最简单的WIN32多线程程序
最简单的WIN32多线程程序
这个例子来自MSDN
这个例子来自MSDN
1 // crt_begthrdex.cpp
2 // compile with: /MT
3 #include <windows.h>
4 #include <stdio.h>
5 #include <process.h>
6
7 unsigned Counter;
8 unsigned __stdcall SecondThreadFunc( void* pArguments )
9 {
10 printf( "In second thread...\n" );
11
12 while ( Counter < 1000000 )
13 Counter++;
14
15 _endthreadex( 0 );
16 return 0;
17 }
18
19 int main()
20 {
21 HANDLE hThread;
22 unsigned threadID;
23
24 printf( "Creating second thread...\n" );
25
26 // Create the second thread.
27 hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );
28
29 // Wait until second thread terminates. If you comment out the line
30 // below, Counter will not be correct because the thread has not
31 // terminated, and Counter most likely has not been incremented to
32 // 1000000 yet.
33 WaitForSingleObject( hThread, INFINITE );
34 printf( "Counter should be 1000000; it is-> %d\n", Counter );
35 // Destroy the thread object.
36 CloseHandle( hThread );
37 }
2009年4月10日星期五
Enum Registry SubKeys in JScript
Enum Registry SubKeys in JScript
I have searched for a good solution to enum the registries with JScript for a long time. Today I got it. The original url is http://www.msghelp.net/showthread.php?tid=65331&page=1 .
The two functions are as below:
The test code is following
I have searched for a good solution to enum the registries with JScript for a long time. Today I got it. The original url is http://www.msghelp.net/showthread.php?tid=65331&page=1 .
The two functions are as below:
function EnumSubKeys(RegKey) {
var RootKey = new Object()
RootKey["HKCR"] = RootKey["HKEY_CLASSES_ROOT"] = 0x80000000;
RootKey["HKCU"] = RootKey["HKEY_CURRENT_USER"] = 0x80000001;
RootKey["HKLM"] = RootKey["HKEY_LOCAL_MACHINE"] = 0x80000002;
RootKey["HKUS"] = RootKey["HKEY_USERS"] = 0x80000003;
RootKey["HKCC"] = RootKey["HKEY_CURRENT_CONFIG"] = 0x80000005;
var RootVal = RootKey[RegKey.substr(0, RegKey.indexOf("\\"))]
if (RootVal != undefined) {
Locator = new ActiveXObject("WbemScripting.SWbemLocator");
ServerConn = Locator.ConnectServer(null, "root\\default");
Registry = ServerConn.Get("StdRegProv");
Method = Registry.Methods_.Item("EnumKey");
p_In = Method.InParameters.SpawnInstance_();
p_In.hDefKey = RootVal;
p_In.sSubKeyName = RegKey.substr(RegKey.indexOf("\\") + 1)
p_Out = Registry.ExecMethod_(Method.Name, p_In);
return p_Out.sNames.toArray();
}
}
function EnumValues(RegKey) {
var RootKey = new Object()
RootKey["HKCR"] = RootKey["HKEY_CLASSES_ROOT"] = 0x80000000;
RootKey["HKCU"] = RootKey["HKEY_CURRENT_USER"] = 0x80000001;
RootKey["HKLM"] = RootKey["HKEY_LOCAL_MACHINE"] = 0x80000002;
RootKey["HKUS"] = RootKey["HKEY_USERS"] = 0x80000003;
RootKey["HKCC"] = RootKey["HKEY_CURRENT_CONFIG"] = 0x80000005;
var RootVal = RootKey[RegKey.substr(0, RegKey.indexOf("\\"))]
if (RootVal != undefined) {
Locator = new ActiveXObject("WbemScripting.SWbemLocator");
ServerConn = Locator.ConnectServer(null, "root\\default");
Registry = ServerConn.Get("StdRegProv");
Method = Registry.Methods_.Item("EnumValues");
p_In = Method.InParameters.SpawnInstance_();
p_In.hDefKey = RootVal;
p_In.sSubKeyName = RegKey.substr(RegKey.indexOf("\\") + 1)
p_Out = Registry.ExecMethod_(Method.Name, p_In);
return p_Out.sNames.toArray();
}
}
The test code is following
var Shell = new ActiveXObject("WScript.Shell")
var Key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
var ValuesArray = EnumValues(Key);
WScript.StdOut.WriteLine("=== Global startup ===")
for (Index in ValuesArray) {
var ValueName = ValuesArray[Index]
ValueValue = Shell.RegRead(Key + "\\" + ValueName)
WScript.StdOut.WriteLine(ValueName + " = " + ValueValue)
}
var Key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
var ValuesArray = EnumSubKeys(Key);
WScript.StdOut.WriteLine("=== Uninstall startup ===")
for (Index in ValuesArray) {
var ValueName = ValuesArray[Index]
WScript.StdOut.WriteLine(ValueName);
}
2009年4月8日星期三
Edit控件的字体和颜色
Edit控件的字体和颜色
字体可以采用函数CreateFont来创建,如下面的例子所示
CFont fnt;
fnt.CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("Lucida Console"));
m_Edit.SetFont(fnt);
fnt.Detach();
Edit控件的字体颜色,背景颜色需要在父窗口中处理消息WM_CTLCOLOREDIT,如下面的函数所示:
LRESULT OnCtlColorEdit(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CDC dc((HDC)wParam);
HWND hwnd = (HWND)lParam;
HBRUSH hbr = 0;
if (m_Edit.m_hWnd == hwnd)
{
dc.SetTextColor(RGB(192,192,192));
dc.SetBkColor(RGB(0,0,0));
hbr = CreateSolidBrush(RGB(0,0,0));
bHandled = TRUE;
}
else
bHandled = FALSE;
dc.Detach();
return (LRESULT)hbr;
}
参考:http://forums.devx.com/showthread.php?t=83993
2009年4月2日星期四
WriteFile,WriteConsole和_tprintf的一些差别
WriteFile,WriteConsole和_tprintf的一些差别
这几个API都是用于输出的,但都有各自的特点:
1. _tprintf的实现利用了WriteFile和WideCharToMultiByte。
2. WriteFile只接受字节流,没有UNICODE的概念,WriteFile可以实现重定向。
3. WriteConsole有两个版本WriteConsoleA和WriteConsoleW, 可以分别接收ANSI和UNICODE字符串,不支持重定向。
1. _tprintf的实现利用了WriteFile和WideCharToMultiByte。
2. WriteFile只接受字节流,没有UNICODE的概念,WriteFile可以实现重定向。
3. WriteConsole有两个版本WriteConsoleA和WriteConsoleW, 可以分别接收ANSI和UNICODE字符串,不支持重定向。
看下面这个简单的程序,编译后再用eXeScope分析一下Import
1 #include <stdio.h>
2
3 void wmain(int argc, wchar_t* argv[])
4 {
5 wprintf(L"Hello World\n");
6 }
看了eXeScope的输出后,发现wprintf的实现利用了WideCharToMultiByte和WriteFile等API,在写入文件前首先是将UNICODE转换成多字节的。
然后本人试着直接调用API进行输出,分别使用了API WriteConsole和WriteFile
1 #include <windows.h>
2
3 #pragma comment(lib, "User32")
4 #pragma comment(lib, "Kernel32")
5 #pragma comment(linker, "/Entry:wmain")
6 #pragma comment(linker, "/Merge:.rdata=.text")
7
8 void *operator new[](unsigned int size){
9 return HeapAlloc (GetProcessHeap(), NULL, size);
10 }
11
12 void operator delete[] (void* memblock){
13 HeapFree (GetProcessHeap(), NULL, memblock);
14 }
15
16 bool WINAPI StdOut( wchar_t* lpString)
17 {
18 HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
19 DWORD numOfCharsWritten=0;
20 WriteConsole(hStdOut, lpString, lstrlen(lpString), &numOfCharsWritten, NULL);
21
22 DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpString, -1, NULL, 0, NULL, false);
23 char *pText = new char[dwNum];
24 WideCharToMultiByte(CP_OEMCP,NULL,lpString,-1,pText,dwNum,NULL,false);
25 BOOL bRet = WriteFile(hStdOut, pText, dwNum, &numOfCharsWritten, NULL);
26 delete[] pText;
27 return bRet;
28 }
29
30 void wmain()
31 {
32 wchar_t *pChar = L"Hello World!\n";
33 StdOut(pChar);
34 }
命令行编译 cl client.cpp /DUNICODE /D_UNICODE /LINK /ALIGN:16
程序执行结果为:
Hello World!
Hello World!
下面的程序Parent.cpp用于输出重定向
1 #include "stdafx.h"
2 #include <windows.h>
3 #include <tchar.h>
4 #include <stdio.h>
5
6 HANDLE SpawnAndRedirect(LPCTSTR commandLine, HANDLE *hStdOutputReadPipe, LPCTSTR lpCurrentDirectory);
7
8 int _tmain()
9 {
10 HANDLE hOutput, hProcess;
11 hProcess = SpawnAndRedirect(_T("client.exe"), &hOutput, NULL);
12 if (!hProcess){
13 _tprintf(_T("Failed to spawn the thread\n"));
14 return 1;
15 }
16
17 char buffer[129];
18 DWORD read;
19 while(ReadFile(hOutput, buffer, 128, &read, NULL))
20 {
21 buffer[read] = '\0';
22 printf("%s\n", buffer);
23 }
24
25 CloseHandle(hOutput);
26 CloseHandle(hProcess);
27
28 return 0;
29 }
30
31
32 // The following function is a shortened variant of Q190351 - HOWTO: Spawn Console Processes with Redirected Standard Handles
33 // There is no special magic here, and this version doesn't address issues like:
34 // - redirecting Input handle
35 // - spawning 16-bits process
36 // - command-line limitations (unsafe 1024-char buffer)
37 // So you might want to use more advanced versions such as the ones you can find on CodeProject
38 HANDLE SpawnAndRedirect(LPCTSTR commandLine, HANDLE *hStdOutputReadPipe, LPCTSTR lpCurrentDirectory)
39 {
40 HANDLE hStdOutputWritePipe, hStdOutput, hStdError;
41 CreatePipe(hStdOutputReadPipe, &hStdOutputWritePipe, NULL, 0); // create a non-inheritable pipe
42 DuplicateHandle(GetCurrentProcess(), hStdOutputWritePipe,
43 GetCurrentProcess(), &hStdOutput, // duplicate the "write" end as inheritable stdout
44 0, TRUE, DUPLICATE_SAME_ACCESS);
45 DuplicateHandle(GetCurrentProcess(), hStdOutput,
46 GetCurrentProcess(), &hStdError, // duplicate stdout as inheritable stderr
47 0, TRUE, DUPLICATE_SAME_ACCESS);
48 CloseHandle(hStdOutputWritePipe); // no longer need the non-inheritable "write" end of the pipe
49
50 PROCESS_INFORMATION pi;
51 STARTUPINFO si;
52 ZeroMemory(&si, sizeof(STARTUPINFO));
53 si.cb = sizeof(STARTUPINFO);
54 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
55 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); // (this is bad on a GUI app)
56 si.hStdOutput = hStdOutput;
57 si.hStdError = hStdError;
58 si.wShowWindow = SW_HIDE; // IMPORTANT: hide subprocess console window
59 TCHAR commandLineCopy[1024]; // CreateProcess requires a modifiable buffer
60 _tcscpy(commandLineCopy, commandLine);
61 if (!CreateProcess( NULL, commandLineCopy, NULL, NULL, TRUE,
62 CREATE_NEW_CONSOLE, NULL, lpCurrentDirectory, &si, &pi))
63 {
64 CloseHandle(hStdOutput);
65 CloseHandle(hStdError);
66 CloseHandle(*hStdOutputReadPipe);
67 *hStdOutputReadPipe = INVALID_HANDLE_VALUE;
68 return NULL;
69 }
70
71 CloseHandle(pi.hThread);
72 CloseHandle(hStdOutput);
73 CloseHandle(hStdError);
74 return pi.hProcess;
75 }
调用Parent,这个程序会创建子进程Client,并且通过pipe将Client的输出定向为Parent的输出,程序的执行结果为
Hello World!
在Client中WriteConsole的输出没有重定向过来!
Hello World!
在Client中WriteConsole的输出没有重定向过来!
订阅:
博文 (Atom)