文章关键字 ‘Windows API’

隐藏系统托盘图标的小程序TrayHider

2010年10月15日,星期五

前几天有人问怎么隐藏程序的系统托盘图标,于是研究了一下,写了个小程序,虽然不知道为什么要隐藏系统托盘图标。

  • 仅支持32位系统,不支持64位
  • 双击左栏图标就可以隐藏对应的程序系统托盘图标
  • 热键Ctrl + Alt + D可以隐藏/显示程序主窗口
  • 支持命令行参数,如TrayHider.exe  QQ.exe隐藏QQ的托盘图标

参考链接:

  1. Вопросик .. для наших Win32 гуру
  2. Shell Tray Info – Arrange your system tray icons
  3. 隐藏Windows系统托盘图标(改进版)

C语言调用API获取程序自身的路径

2010年10月14日,星期四

VBS获取程序自身的路径很简单

WScript.Echo WScript.ScriptFullName

C语言其实也也很简单,只可惜以前太菜

TCHAR szFileName[MAX_PATH];
GetModuleFileName(NULL, szFileName, MAX_PATH);
MessageBox(NULL, szFileName, TEXT(""), 0);

参考链接:GetModuleFileName Function

GUI程序获取命令行参数

2010年10月13日,星期三

在Console程序中可以用main函数中的argc和argv遍历命令行参数。

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i;
    for(i = 0;i < argc;i++)
        printf("%s\n", argv[i]);
    return 0;
}

那么在GUI程序中怎么遍历命令行参数呢?虽然WinMain函数的lpCmdLine参数中传入了程序的命令行参数,但是该参数不包含应用程序名(即main函数中的argv[0]),而且自己解析出每个参数也比较麻烦。

最简单的方法是先用GetCommandLineW函数获取命令行,然后用CommandLineToArgvW函数将命令行转化成C语言main函数argc和argv的形式。

#include <windows.h>
#include <stdio.h>
#include <shellapi.h>

int WINAPI WinMain(HINSTANCE hInstance, 
            HINSTANCE hPrevInstance, 
            LPSTR lpCmdLine, 
            int nShowCmd)
{
    LPWSTR *szArglist;
    int nArgs, i;
    
    szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
    for (i = 0; i < nArgs; i++)
    {
        MessageBoxW(NULL, szArglist[i], L"", 0);
    }
    return 0;
}

只可惜没有CommandLineToArgvA函数,想用ANSI版的话得自己用WideCharToMultiByte函数转换一下。

VC6中使用高版本API的方法

2010年10月10日,星期日

今天用VC6重新编译一个以前写过的程序。程序中使用了API函数SetWindowsHookEx,某段代码如下

SetWindowsHookEx(WH_KEYBOARD_LL,KeyHookProc,hInstance,0);

Visual Studio 2008太大了我没有安装,只安装了Visual C++ 6.0和Microsoft Platform SDK February 2003。这个程序以前用VC9(即VC2008)编译没有任何问题,但是今天用VC6编译的时候竟然报错:

error C2065: 'WH_KEYBOARD_LL' : undeclared identifier

MSDN文档上说WH_KEYBOARD_LL要求系统必须至少为Windows NT/2000/XP,我的系统是Windows 2008 R2,怎么还会报错说未定义呢?百思不得其解。

文档说WH_KEYBOARD_LL Declared in Winuser.h,好吧,我就打开Winuser.h看了一下,终于找到了原因:

#if (_WIN32_WINNT >= 0x0400)
#define WH_KEYBOARD_LL     13
#define WH_MOUSE_LL        14
#endif // (_WIN32_WINNT >= 0x0400)

罪魁祸首就是这个_WIN32_WINNT,只有当它大于0x0400的时候才定义WH_KEYBOARD_LL。

(更多…)

VBS调用Windows API函数

2010年08月7日,星期六

那天无意中搜索到一篇《WinCC VBS利用EXCEL调用Windows API函数》的文章,不知道WinCC是什么,Google了一下好像跟西门子自动化有关。WinCC是什么并不重要,重要的是这篇文章提供了VBS调用Windows API的一种思路——EXCEL VBA,一种传说比VB还要VB的语言。

但是那篇文章中的例子都是使用已经写好的EXCEL VBA程序,即首先得存在一个EXCEL文件。我就想,能不能在VBS中通过excel.application对象创建一个包含VBA代码的EXCEL文档然后再调用它呢?Google来Google去,终于在微软帮助和支持中找到了方法。

结合两篇文章(请先阅读这两篇文章),写了一个示例程序,效果是移动鼠标至桌面左上角。如果你的EXCEL不是太盗版,双击这个VBS后应该可以看到效果。

Dim WshShell
set WshShell = CreateObject("wscript.Shell")
WshShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Excel\Security\AccessVBOM",1,"REG_DWORD"
WshShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Security\AccessVBOM",1,"REG_DWORD"
WshShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Excel\Security\AccessVBOM",1,"REG_DWORD"
Dim oExcel, oBook, oModule
Set oExcel = CreateObject("excel.application")
Set oBook = oExcel.Workbooks.Add
Set oModule = obook.VBProject.VBComponents.Add(1)
strCode = _
"Private Declare Function SetCursorPos Lib ""user32"" (ByVal x As Long, ByVal y As Long) As Long" & vbCr & _
"Sub MyMacro(x as Long, y as Long)" & vbCr & _
"SetCursorPos x, y" & vbCr & _
"End Sub"
oModule.CodeModule.AddFromString strCode
oExcel.Run "MyMacro",0,0
oExcel.DisplayAlerts = False
oBook.Close
oExcel.Quit

前面3-5行的修改注册表是为了让VBS能够完全控制EXCEL,strCode即为写入EXCEL中的VBA代码,至于怎样在VBA中调用Windows API不属于本文的讨论范围,请自己查阅资料。使用oExcel.Run "MyMacro",0,0调用我们写入的VBA代码。