本人正在撰寫一個股票自動交易軟體,所以學了兩個月的DELPHI,以前沒接觸過編程,但出于保密的需要,不得不自己來編程。有網路真好,有那么多的資源,在這里真的太感謝了,可以上網學清華大學教授的課程,咱也上清華了。DELPHI真的沒落了,去書店買了兩本書,過了一個月,又去書店發現DELPHI的書少了不少,只有不超過十種了,這可是哈爾濱市最大的書店學府書店呢。不過DELPHI真的簡單易學,很好入門,就是感覺資料型別的轉換太麻煩,兼容性太差了,一條陳述句轉來轉去我都暈了。還有四舍五入應該有常用的型別。
學了兩周咱就開始編程的萬里長征了,這種目標驅動的方式學習起來就是效率高。
最后需要控制交易軟體進行交易了。好不容易找到程式的句柄可以調出賣出視窗了,可是增加代碼,價格,數量等視窗卻沒了辦法,象堵墻。后來在網上找了個做程式設計的朋友,在他的熱心幫助下總算有了點進展,在這里表示感謝呀。
網上的資源給了咱那么大的幫助,咱也得做點貢獻呀。我是菜鳥,編程才學兩個月,自然不足之處漏洞百出,大家不要笑話呀。獻丑了,我想有挺多象我這樣的初學者,所以做點說明,
procedure TForm1.Button7Click(Sender: TObject);
var
i,j,k:integer;
ck_hwnd,qr_hwnd,zh_hwnd,lyg_hwnd:HWND;
strl1,strl2,strl3:TstringList;
flag:Boolean;
begin
pCode:= '002377';
buyPrice:='8.94';
buyNum:='100';
ck_hwnd:=FindWindow(nil,'網上股票交易系統5.0');//找到交易軟體的句柄,這里要用SPY++,
if ListView1.Items.Count <>0 then
begin
for i:=0 to listview1.items.count-1 do
begin
listview1.Items[i].SubItems[1] := floattostr(strtofloat(listview1.Items[i].SubItems[1])+0.01);
if strtofloat(listview1.Items[i].SubItems[1])>strtofloat(listview1.Items[i].SubItems[5]) then
begin
postmessage(ck_hwnd,wm_keydown,vk_f2,0);//對交易軟體發出賣出指令,我的交易軟體賣出快捷鍵是F2。
PostMessage(ck_hwnd,wm_keyup,VK_F2,0);
sendMessage(mcdm,WM_SETTEXT,0,LongInt(Pchar(pCode))); //以下三句所用的句柄mcdm,mcjg,mcsl,分別對應我//的軟體里的代碼,賣出價格,賣出數量三個輸入框,這三個句柄是在程式視窗啟動時獲得的,怎樣獲取最后再詳細說明吧。
SendMessage(mcjg,WM_SETTEXT,0,LongInt(Pchar(buyPrice)));
SendMessage(mcsl,WM_SETTEXT,0,LongInt(Pchar(buynum)));
Sleep(400);
AssignFile(f,'d:\SYjb.txt');
Rewrite(f);
EnumWindows(@EnumWindowsProc, 0);
closefile(f);
strl1:=Tstringlist.create;
strl1.loadfromfile('d:\syjb.txt');//以上是找到交易軟體的所有句柄,因為要彈出視窗了。我把它保存到一個檔案檔案里了,其它不用保存的,我只是為了直觀。這樣更好理解,更好比較句柄發生的變化。
postMessage(mcj,BM_CLICK,0,0);//此條陳述句為點擊賣出鍵,mcj句柄也是在程式啟動時獲得的。
Sleep(500);
AssignFile(f,'d:\SYjb.txt');
Rewrite(f);
EnumWindows(@EnumWindowsProc, 0);
closefile(f);//再次獲取交易軟體的所有句柄,因為點擊了賣出鍵有彈出視窗了。
strl2:=tstringlist.create;
strl3:=tstringlist.create;
strl2.loadfromfile('d:\syjb.txt');
for j:=0 to strl2.count-1 do
begin
flag:=true;//標記設為真
for k:=0 to strl1.count-1 do
begin
if strl2[j]=strl1[k] then
begin
flag:=false;//如果有相同的,把標記設為假
break;
end;
end;
if flag then//標記為真,表示沒有相同的,加到了第三個字串列中
begin
strl3.add(strl2[j]);
end;
end;//比較視窗彈出前后兩個句柄檔案的不同,把它寫入strl3。這里多了兩個句柄,strl[0] 是第一個,不知是什么,請高手告之,strl[1]是第二個,這個就是我要找的句柄了,新彈出視窗的句柄。
lyg_hwnd:=strtoint(strl3[1]);
zh_hwnd:=FindWindowEx(lyg_hwnd,0,'Button',nil);通過新彈出視窗,找到‘賣出’鍵句柄。
postMessage(zh_hwnd,BM_CLICK,0,0);//按‘賣出’鍵。
//再次查找‘確定’鍵,因為又彈出了新視窗,讓你確定。
AssignFile(f,'d:\SYjb.txt');
Rewrite(f);
EnumWindows(@EnumWindowsProc, 0);
closefile(f);
strl2.clear;
strl3.clear;
strl2.loadfromfile('d:\syjb.txt');
for j:=0 to strl2.count-1 do
begin
flag:=true;//標記設為真
for k:=0 to strl1.count-1 do
begin
if strl2[j]=strl1[k] then
begin
flag:=false;//如果有相同的,把標記設為假
break;
end;
end;
if flag then//標記為真,表示沒有相同的,加到了第三個字串列中
begin
strl3.add(strl2[j]);
end;
end;
strl3.SaveToFile('D:\DDDDD.TXT');
Sleep(300);
qr_hwnd:=strtoint(strl3[1])+65536;
zh_hwnd:=FindWindowEx(qr_hwnd,0,'Button','確定');//這就是我要找的‘確定’鍵。
Sleep(300);
sendmessage(zh_hwnd,wm_lbuttondown,0,0);
sendmessage(zh_hwnd,wm_lbuttonup,0,0);//點擊‘確定’鍵賣出。
strl1.Free;
strl2.Free;
strl3.Free;
end;
end;
end;
end;
function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): Boolean; stdcall; // 程式中要呼叫的
var
buf: array[Byte] of Char;
sjb:string;
begin
GetWindowText(hwnd, buf, SizeOf(buf));
sjb:=inttostr(hwnd);
Writeln(f,sjb);
Result := True;
end;
總體思路如下:在程式啟動前先啟動交易軟體,程式一啟動,表單的ONSHOW先執行找到交易軟體的所有句柄,寫入一個文本檔案,安裝SPY++軟體,啟動之,用SPY++查找你要的輸入框句柄,需要注意的是SPY++找到的句柄是十六進制,用附件自帶的計算器轉換成十進制。找開程式啟動時所有句柄檔案D:\jb.txt.這是個十進制的句柄檔案,搜索已用計算器轉換的句柄,找到后查一下它所在的行數,(我一般用WORD找開檔案,這樣行數特好找)如我的mcdm句柄在檔案中的行數為175,那它的句柄就是T[174],這是個文本,使用時需要轉換成整型。有了句柄,想干什么都行了。基本思路就是交易軟體每次啟動句柄都變化,但所有句柄通過獲取的方式它的位置不變。
Handle:=findWindow(nil,'網上股票交易系統5.0');
AssignFile(f, 'd:\jb.txt');
Rewrite(f);
EnumChildWindows(Handle, @GetAllHandle, Integer(@Handle));
closeFile(f);
t:=Tstringlist.Create;
t.LoadFromFile( 'd:\jb.txt ');
mcdm:=StrToInt(t[174]);
mcjg:=strtoint(t[176]);
mcsl:=strtoint(t[178]);
mcj:=strtoint(t[179]);//以上這段是我的程式視窗啟動中的一段。
function GetAllHandle(hwnd: Integer; lparam: Longint):Boolean; stdcall;//上段需要呼叫的。
var
buffer: array[0..255] of Char;
sjb:string;
begin
Result := True;
GetClassName(hwnd,buffer,256);
sjb:=format('%d',[hwnd,StrPas(Buffer)]);
Writeln(f,sjb);
end;
基本思路就是軟體每次啟動句柄都變化,但所有句柄通過獲取的方式它的位置不變。
彈出視窗通過以上方式卻獲取不了,解決方法是彈出之前查找windows下的所有前活動視窗句柄,彈出之這后再查找一次。
比較后新增的就是彈出視窗的句柄。(不知為什么是兩個,后一個是,請高手做答吧)。
現在我的自動交易軟體基本完成了。從網上獲取股票實時資料,進行監控。不知有沒有人對此感興趣,如果有我改天把這個軟體發上來與大家共享吧。
拋個磚希望別把大家砸到。哈哈。
uj5u.com熱心網友回復:
大蝦,我很感興趣,給我來一份[email protected]
uj5u.com熱心網友回復:
好復雜,不能什么時候彈出什么視窗把他寫死嗎,視窗名是你自己定的,需要的時候SHOW一下不行嗎uj5u.com熱心網友回復:
大俠,其實是高手,能給我一份么?[email protected]uj5u.com熱心網友回復:
說實話我不太喜歡通過找句柄控制別人程式,像在偷東西,還不穩定uj5u.com熱心網友回復:
學習,能給我一份么 [email protected]uj5u.com熱心網友回復:
如果股票軟體像MetaTrader那樣方便就好了uj5u.com熱心網友回復:
請發一份到[email protected]uj5u.com熱心網友回復:
[email protected] 感興趣呀uj5u.com熱心網友回復:
發一個,[email protected]uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
網上的資源給了咱那么大的幫助,咱也得做點貢獻呀 ;[color=#FF0000][/color]
給你個思路吧,對于彈出視窗,可以用GetForegroundWindow();API可以獲得當前焦點視窗的句柄,
uj5u.com熱心網友回復:
我也正想寫這樣的軟體,請問你那個好用不,會不會常死機,
求分享
[email protected]
uj5u.com熱心網友回復:
不如根據股軟的界面特點,發送滑鼠點擊到要控制的控制元件,發送按鍵,這樣輸入提交,然后回到自己的程式,整個程序很快,用戶不會感到特別的不適。uj5u.com熱心網友回復:
按你的思路,但我發現,獲取買入賣出的句柄和位置,都是變化的,uj5u.com熱心網友回復:
不錯學習二個月,涉及的東東,是別人二年也學不來的!!!uj5u.com熱心網友回復:
支持
uj5u.com熱心網友回復:
句柄變可以理解,但是位置變,就很奇怪,現在終于明白原因了,跟打開軟體的順序有關系。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/90352.html
標籤:語言基礎/算法/系統設計
上一篇:如何判斷TWebBrowser中的某個Frame是否被指定了新的URL
下一篇:求助Delphi怎么找常量?
