编程 & 生活 -- 西西吹雪

开心工作,快乐生活 (原创文章,转载请注明出处)

导航

我开发共享软件的三次经历(上):打造一款很多人用的软件

共享软件这个词,如今似乎离我们已经越来越遥远了。还有人有用WinZip吗?还有人记得netants吗?这些辉煌一时的明星,已逐渐消失在人们的视野中。今天已经是免费软件的世界。互联网行业的巨头们,打造的免费模式,给共享软件敲响了丧钟。

共享软件,曾经寄托了多少程序员们创业致富的梦想。我也曾加入共享软件的大潮中,用业余时间开发过差不多近十个共享软件,最后它们大都灰飞烟灭了,但其中三次经历,还是给我的程序员生涯留下了难以磨灭的记忆。

第一个:隐藏专家

只赚了不到一千块。虽然一直处于自生自灭的状态,但却用户数最多。05年的时候曾统计过各大网站的下载量,当时就达十几万的下载量,时至今日,相信用过这个软件的人数,绝不是一个小数目。尽管差不多十年没有更新了,仍然不时有用户找到我要注册码,或者提出改进建议。曾经在《电脑报》上被刊文介绍,还被收录到几本杂志的光盘中。

第二个:淘宝发布大王

赚到了十万多一点。这一次总算把握住了先机,模仿者无数。后来由于环境变化,软件失去了价值,自然消失。虽然赚的钱不算多,但却在一定程度上改变了我的生活,因为靠着这十万元,在这个寸土寸金的大城市里,我终于有了一块自己的立足之地。

第三个:易创招标通

这次野心最大,花我精力最多,却只赚了几千块,最后彻底放弃。这一次给我留下了太多的经验教训,估计一辈子我也不会忘记。

      本人拙作《程序员第二步-从程序员到项目经理》已经由人民邮电出版社出版,当当网京东网均可预订,谢谢各位园友们的长期大力支持!

 

第一篇:隐藏专家-打造一款很多人用的软件

从当程序员的那一天起,我就一起有一个梦想,就是开发一款有很多人用的软件,果能如此的话,这一生也算是有所价值,没有白过。我第一次开发的共享软件,隐藏专家,差点就实现了我的这个梦想。虽然一直处于自生自灭的状态,但用户并不少,光多特网站的下载量就达5万多,相信用过这款软件的人,总该有几十万吧。尽管差不多十年没有更新了,仍然不时有用户找到我要注册码,或者提出改进建议。曾经在《电脑报》上被刊文介绍,还被收录到几本杂志的光盘中。

隐藏专家是一个很简单的软件,它的功能可以用一句话说清楚:按下快捷键,立即隐藏指定的窗口和托盘图标。开发这个软件,最开始是给自己用的,当看到领导朝这边走来时,我轻轻按下Alt+X,QQ窗口、IE浏览器,连接QQ托盘图标全部都会消失的得无影无踪。

隐藏专家是2002年用Delphi开发的。写这个软件,还有一个目的,就是学习。我当时对于写程序还是初入门,对于程序代码是怎样工作的,还一点也不懂。通过开发隐藏专家,我对Windows消息机制,终于有了比较清楚的认识,同时也学会了不少Windows API的用法。

这里要感谢一下“大富翁论坛”,这是一个当年非常火爆的Delphi技术论坛,从上面我下载了一个近300M的离线资料,至今还保存在我的移动硬盘上。我几乎把每一篇都看过,实在是受益匪浅,可以说,大富翁论坛就是我的启蒙老师。

  

下面介绍一下这个小软件所用的到一些关键技术:

1.窗口隐藏:

要隐藏窗口,首先要找到窗口,就是遍历所有的窗口(FinWindow, GetWindow两个API),然后看窗口标题文字是否符合设定的条件,如果符合,就隐藏或显示该窗口(ShowWindow),这些都是通过Windows API来实现的。

主要代码如下所示:

//显示或隐藏标题在winlist中的所有窗口。
procedure HideWindow(WinList:TStringList);
var
  hCurWindow:HWND;
  WinText:Array[0..255of char;
  i:integer;
begin
  if winList = nil then exit;
    hCurWindow:=GetWindow(FindWindow('Shell_TrayWnd',nil),GW_HWNDFirst);
  While hCurWindow<>0 do
  begin
     if GetWindowText(hCurWindow,@WinText,255)>0 then
     begin
        for i:=0 to winlist.Count-1 do
        begin
           if pos(lowercase(winlist.Strings[i]),lowercase(StrPas(@Wintext)))>0 then
           begin
             if IsShow then
               begin
                 //隐藏窗口
                 ShowWindow(GetWindow(hCurWindow,GW_OWNER),SW_HIDE);
                 ShowWindow(hCurWindow,SW_HIDE);
               end
             else
               begin
                 ShowWindow(GetWindow(hCurWindow,GW_OWNER),SW_SHOW);
                 ShowWindow(hCurWindow,SW_SHOW);
               end;
           end;
        end;
     end;
     hCurWindow:=GetWindow(hCurWindow,GW_HWNDNEXT);
  end;
end;

2.托盘图标隐藏

这个功能网上基本上没什么资料,费了我不少时间。经过长时间的琢磨,终于找到了解决之道。我用spy++观察托盘区,发现图标都在一个类名为ToolbarWindow32的工具条窗口中,既然如此,应该可以有相应的方法,读出工具条某个按钮的文字信息,以及通过发送消息将其显示或隐藏。顺滕模瓜,最后终于找到了解决方法:

 

//取得托盘区图标列表所在的窗口句柄,是一个toolbarwindow32类的工具条
function GetTrayHandle():THandle;   
var
 wnd,wnd2:HWND;
begin
  wnd := FindWindow('Shell_TrayWnd',nil);
  wnd2 := FindWindowEx(wnd,0,'TrayNotifyWnd',nil);
  wnd := FindWindowEx(wnd2,0,'ToolbarWindow32',nil);
  if wnd=0 then
  begin
    wnd := FindWindowEx(wnd2,0,'TrayClockWClass',nil);
    wnd := GetNextWindow(wnd,GW_HWNDNEXT);
    wnd := FindWindowEx(wnd,0,'ToolbarWindow32',nil);
    result := wnd;
  end
  else
    result := wnd;
end;

//隐藏托盘图标的函数
procedure HideIcon(strHint:string;bHide:boolean);
var
 nItemCount,i:integer;
 chBuffer:array[0..255of char;
 dwProcessID:DWORD;
 hProcess:Cardinal;
 adPointer:Pointer;
 nNumberOfBytesRead:Cardinal;
 bi:TTBBUTTON;
 hWindow:THandle;
 str1,str2:string;
begin
  str1 := lowercase(strHint);
  hWindow := GetTrayHandle;
  nItemCount := SendMessage(hWindow, TB_BUTTONCOUNT, 00);
  GetWindowThreadProcessId(hWindow, @dwProcessID);
  hProcess := OpenProcess(PROCESS_VM_OPERATION + PROCESS_VM_READ + PROCESS_VM_WRITE,
                    false,
                    dwProcessID);
  adPointer := VirtualAllocEx(hProcess,
                            nil,
                            4096,
                            MEM_RESERVE + MEM_COMMIT,
                            PAGE_READWRITE);
    try
      for i:=0 to nItemCount do
      begin
           //获取工具条按钮的提示文字信息
         SendMessage(hWindow, TB_GETBUTTON, i, integer(adPointer));
         ReadProcessMemory(hProcess,
                          (adPointer),
                          @bi,
                          sizeof(bi),
                          nNumberOfBytesRead);
         SendMessage(hWindow, TB_GETBUTTONTEXT , bi.idCommand, integer(adPointer));
         ReadProcessMemory(hProcess,
                      adPointer,
                      @chBuffer,
                      sizeof(chBuffer),
                      nNumberOfBytesRead);

        //比对文字,判断是否为要隐藏的图标
        str2:= lowercase(chBuffer);
        if pos(str1,str2)>0 then
        begin
          if bHide then
            sendmessage(hWindow,TB_HIDEBUTTON,bi.idCommand,makelong(1,0))
          else
            sendmessage(hWindow,TB_HIDEBUTTON,bi.idCommand,makelong(0,0));
          exit;
        end;
      end
    finally
       VirtualFreeEx(hProcess,
                    adPointer,
                    0,
                    MEM_RELEASE);
      CloseHandle(hProcess);
    end;
end;

3.全局热键注册

隐藏窗口的快捷键必须在任何情况下都可以使用,主要用到一个API函数:RegisterHotKey,如果取消注册,则调用UnRegisterHotKey。

软件还有一个屏蔽用户键盘和鼠标输入的功能,当屏蔽时,用户不能进行任何键盘和鼠标的操作,就像死机了一样,这个功能需要另一个API函数来实现,就是SetWindowsHookEx,这个函数可以设置一个全局钩子,“钩住”键盘消息和鼠标消息,自己进行处理。如果要取消钩子,则调用unhookWindowsHookEx函数来实现。

 

隐藏专家这个软件,总共收了不到1000元注册费,其中还有几百块是在天空软件站的账户,由于我长期没有去维护,后来竟然发现被账户被注销了,至于这几百块钱,也不知所踪。更让人生气的是,隐藏专家在天空软件站上也不翼而飞,再也找不到了。隐藏专家从定位来说,应该说还是抓住了不少用户的心理,具有不错的实用性。之所以没有成功,我将原因归结为三点:一是包装不够;二是缺乏营销;三是国内共享软件的生存环境不佳。

这一次经历,让我明白了做共享软件赚钱并不容易,特别针对国内市场。后来我看到一篇文章,讲一个程序员做了一个mp3转CD的软件,在国外市场一个月可以收到5万美金的注册费,原来小软件确实是可以赚大钱的。我动了心,可惜由于功力未够,一直未能将其推广到国外,总归是一件遗憾的事情。

不过到今天,我想是该发布一个永久免费版了,既然赚不到钱,何不免费让更多人来用,这不也能有助于达成我很久以前的心愿——开发一款很多人用的软件吗?只要有人还要用它,也许也算是一种成功吧。

  ---------------------------------

        本人拙作《程序员第二步--从程序员到项目经理》已经由人民邮电出版社出版,谢谢各位园友的长期支持!

        当当网:http://product.dangdang.com/23365823.html 

        京东网:http://item.jd.com/11350488.html     

 

posted on 2013-11-26 10:00  西西吹雪  阅读(15731)  评论(49编辑  收藏  举报