我开发共享软件的三次经历(上):打造一款很多人用的软件
共享软件这个词,如今似乎离我们已经越来越遥远了。还有人有用WinZip吗?还有人记得netants吗?这些辉煌一时的明星,已逐渐消失在人们的视野中。今天已经是免费软件的世界。互联网行业的巨头们,打造的免费模式,给共享软件敲响了丧钟。
共享软件,曾经寄托了多少程序员们创业致富的梦想。我也曾加入共享软件的大潮中,用业余时间开发过差不多近十个共享软件,最后它们大都灰飞烟灭了,但其中三次经历,还是给我的程序员生涯留下了难以磨灭的记忆。
第一个:隐藏专家
只赚了不到一千块。虽然一直处于自生自灭的状态,但却用户数最多。05年的时候曾统计过各大网站的下载量,当时就达十几万的下载量,时至今日,相信用过这个软件的人数,绝不是一个小数目。尽管差不多十年没有更新了,仍然不时有用户找到我要注册码,或者提出改进建议。曾经在《电脑报》上被刊文介绍,还被收录到几本杂志的光盘中。
第二个:淘宝发布大王
赚到了十万多一点。这一次总算把握住了先机,模仿者无数。后来由于环境变化,软件失去了价值,自然消失。虽然赚的钱不算多,但却在一定程度上改变了我的生活,因为靠着这十万元,在这个寸土寸金的大城市里,我终于有了一块自己的立足之地。
第三个:易创招标通
这次野心最大,花我精力最多,却只赚了几千块,最后彻底放弃。这一次给我留下了太多的经验教训,估计一辈子我也不会忘记。
本人拙作《程序员第二步-从程序员到项目经理》已经由人民邮电出版社出版,当当网京东网均可预订,谢谢各位园友们的长期大力支持!
第一篇:隐藏专家-打造一款很多人用的软件
从当程序员的那一天起,我就一起有一个梦想,就是开发一款有很多人用的软件,果能如此的话,这一生也算是有所价值,没有白过。我第一次开发的共享软件,隐藏专家,差点就实现了我的这个梦想。虽然一直处于自生自灭的状态,但用户并不少,光多特网站的下载量就达5万多,相信用过这款软件的人,总该有几十万吧。尽管差不多十年没有更新了,仍然不时有用户找到我要注册码,或者提出改进建议。曾经在《电脑报》上被刊文介绍,还被收录到几本杂志的光盘中。
隐藏专家是一个很简单的软件,它的功能可以用一句话说清楚:按下快捷键,立即隐藏指定的窗口和托盘图标。开发这个软件,最开始是给自己用的,当看到领导朝这边走来时,我轻轻按下Alt+X,QQ窗口、IE浏览器,连接QQ托盘图标全部都会消失的得无影无踪。
隐藏专家是2002年用Delphi开发的。写这个软件,还有一个目的,就是学习。我当时对于写程序还是初入门,对于程序代码是怎样工作的,还一点也不懂。通过开发隐藏专家,我对Windows消息机制,终于有了比较清楚的认识,同时也学会了不少Windows API的用法。
这里要感谢一下“大富翁论坛”,这是一个当年非常火爆的Delphi技术论坛,从上面我下载了一个近300M的离线资料,至今还保存在我的移动硬盘上。我几乎把每一篇都看过,实在是受益匪浅,可以说,大富翁论坛就是我的启蒙老师。
下面介绍一下这个小软件所用的到一些关键技术:
1.窗口隐藏:
要隐藏窗口,首先要找到窗口,就是遍历所有的窗口(FinWindow, GetWindow两个API),然后看窗口标题文字是否符合设定的条件,如果符合,就隐藏或显示该窗口(ShowWindow),这些都是通过Windows API来实现的。
主要代码如下所示:
var
hCurWindow:HWND;
WinText:Array[0..255] of 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的工具条窗口中,既然如此,应该可以有相应的方法,读出工具条某个按钮的文字信息,以及通过发送消息将其显示或隐藏。顺滕模瓜,最后终于找到了解决方法:
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..255] of 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, 0, 0);
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
转载于:https://www.cnblogs.com/ShaYeBlog/p/3457660.html
我开发共享软件的三次经历(上):打造一款很多人用的软件相关推荐
- 我开发共享软件的三次经历(中):我赚到了十万块
共享软件这个词,如今似乎离我们已经越来越遥远了.还有人记得超级兔子吗?还有人知道netants吗?这些辉煌一时的明星,已逐渐消失在人们的视野中.今天已经是免费软件的世界.互联网行业的巨头们,打造的免费 ...
- Python只需要三十行代码,打造一款简单的人工语音对话
@Author:Runsen 1876年,亚历山大·格雷厄姆·贝尔(Alexander Graham Bell)发明了一种电报机,可以通过电线传输音频.托马斯·爱迪生(Thomas Edison)于1 ...
- 苹果vs剪辑下载_秒简iPhone上的一款免费手机视频剪辑软件,支持导入视频或图片...
在这个短视频超火的网络时代,人人都可以分享属于自己的短视频内容.没有一款得心应手的视频剪辑制作软件那怎么行? 前段时间,小编更新了安卓手机上的一款视频剪辑处理制作软件. 链接:点击此处 今天,小编为大 ...
- web前端开发到底是自学还是去上培训班?
web前端开发到底是自学还是去上培训班,纠结中...... 应届毕业生,软件技术专业,去年接触到web前端开发这个行业,但是迷迷糊糊的就知道HTML +CSS +JS ,其他一无所知,就知道做网页加一 ...
- 电子计算机的思维导图,电脑上最好用的6款,思维导图软件测评
我经常会把自己绘制的思维导图发在一些媒体网站上,于是不断有人会私信如何创作思维导图?哪一款思维导图好用?想系统学习下思维导图,有推荐的书或者课程吗?如何利用思维导图记忆文科?有什么好用又免费的思维导图 ...
- 待办事项桌面插件_求一款安卓手机上可添加小目标的桌面便签软件?
随着国产安卓手机的发展和进步,现在使用安卓手机的用户是越来越多了,我的闺蜜小张之前使用的是苹果手机,最近她更换了一款华为新出的mate40手机.对于这款华为旗舰手机,小张使用了几天后表示是非常满意的, ...
- 矛与盾---走出软件作坊:三五个人十来条枪 如何成为开发正规军(三十五)
我一直很犹豫该不该写这一主题,也很犹豫该怎么写这一主题,对于这一主题该起什么名字更让我反复修改了多次无法确定现在的这个标题是否合适. 对,这个主题就是关于"利"的,关于大家的工资该 ...
- GitHub 优秀的 Android 开源项目 淘宝技术牛p博客整理开发中最常用的GitHub上 优秀的 Android 开源项目整理(精品)...
原文地址为http://www.trinea.cn/android/android-open-source-projects-view/,作者Trinea 主要介绍那些不错个性化的View,包括Lis ...
- 做开发几年的个人经历
楼主2007年从一家天津的三流大学毕业.毕业前报了一个职位培训,毕业后可以推荐工作.因为推荐的公司都是北京的,所以就来北京了. 找了一个月工作,没有找到要我的,就在出租屋里宅了起来,打着考研的旗号,又 ...
- 地主家也没有余粮了---走出软件作坊:三五个人十来条枪 如何成为开发正规军(三十六)
有个网友给我的留言让我陷于深思. 他是一个十来条枪公司的小老板.他的困境也是许多同样规模小软件公司的困境.我也有不少朋友创业,他们所处的困境都是相似的. 大家都是差不多认识几个客户,然后觉得时机成熟了 ...
最新文章
- Silverlight获取WebHost配置信息--WebClient和XmlSerializer模拟
- 11年的计算机二级vf考试试题,2011年计算机等级考试二级VFP 辅助练习题及答案
- Vim 80列布局问题
- python url编码 空格_使用请求和python时URL中的空格
- mysql5.5数据库安装
- 用Vue来实现购物车功能(二)
- Valgrind概述
- JSON基础 JS操作JSON总结
- [转载].一直不怎么明白PID的运算输出结果怎么换算成执行机构的控制量
- position: relative_设置relative 后再设置定位 原有位置空白
- android: ListView设置emptyView 误区
- lg v35 thinkq刷韩版android9.0教程
- Maven项目 cityFileFK02数据库连接(课外完成)
- MySQLSyntaxException:FUNCTION xxxxxxxx.JSON_EXTRACT does not exist
- 别在找提高C++晦涩难懂的知识了。提高效率!这里有C++STL——全面总结详细教程(附案例解析)(持续更新中)
- 数据分析软件解读王者荣耀一年的“王者”成绩单
- 数智化未来5大趋势——CDEC2020中国数字智能生态大会上海站生态伙伴发展状况调查...
- 重读经典:《End-to-End Object Detection with Transformers》
- 单片机交通灯灯c语言程序,51单片机用C语言实现交通灯(红绿灯)源程序
- \int_0^{+\infty} \frac{\sin x}{x}\mathop{}\!\mathrm{d}{x}
热门文章
- NOIP 2005 等价表达式 (TYVJ P1060)
- Linux重定向和管道的基础学习
- nginx-0.1.0文件分析2: ngx_socket.c
- 三阶段提交协议(有限状态自动机)
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
- echarts--(2)--创建一个饼图
- fio 磁盘I/O测试工具
- kill、killall 、pkill 发送信号命令
- nginx负载均衡核心模块(upstream和proxy模块)及常用参数介绍
- 微信小程序获取是android还是ios,微信小程序-手机操作系统以及微信版本判断