線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4194
推到 Plurk!
推到 Facebook!

如何使用一個按鈕來執行另一個程式

尚未結案
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-05-12 20:12:10 IP:218.162.xxx.xxx 未訂閱
我想我把我比較會的C寫好後..exe檔 經由BCB的介面來去執行它 然後出來的結果秀在BCB上 (結果都是文字檔而已)然後再存檔 這樣可以嗎? 要怎樣做呢? 謝謝^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-05-12 20:43:00 IP:218.19.xxx.xxx 未訂閱
Miki-lion 您好:    要執行外部程式可使用 Windows API 的 ShellExecute() 來完成,使用方式可參考這一篇:    http://delphi.ktop.com.tw/topic.php?topic_id=55573 兩支程式之間的資料傳遞可以參考這一篇: http://delphi.ktop.com.tw/topic.php?topic_id=27080 或者您也可以在被呼叫的程式中將處理結果存成文字檔,然後再由呼叫的那支程式讀出來做其它的處理。 發表人 - RedSnow 於 2005/05/12 20:50:15
windblown
中階會員


發表:0
回覆:117
積分:98
註冊:2003-11-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-05-12 21:50:07 IP:219.84.xxx.xxx 未訂閱
To Miki-lion 我會建議你把你自己寫的部分集中在自己的 .cpp 中,然後用 .h 讓 BCB 來呼叫;這樣的話,未來可以給其他部分使用,也可以給其他 compiler 來編譯。
cashyy
高階會員


發表:117
回覆:322
積分:212
註冊:2004-04-30

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-05-13 03:17:20 IP:211.74.xxx.xxx 未訂閱
妳好!我同意用windblown大大的方法!把自己的程式碼寫成Function! 參考範例:
//.cpp
#include     #include <math.h>    #pragma hdrstop    #include "bcb.h"    //---------------------------------------------------------------------------
// 以下為 aspect 函式之程式碼
// 功能:主要為印出星號
// 傳入參數:iaspect(型態 int)         EX: iaspect = 3;
//---------------------------------------------------------------------------
void Taspect::aspect(int iaspect,TMemo *Memo)
{
  int i,j,k;
  for(i=1;i<=iaspect;i  )
  {
    for(j=1;j<=(iaspect-i) 1;j  )
      Memo->Lines->Add(" ");
    for(k=1;k<=(i*2)-1;k  )
      Memo->Lines->Add("*");
  }
}    //---------------------------------------------------------------------------    //.h
/* 防止標頭檔的重複引入 */
#ifndef _bcb_H_
#define _bcb_H_
#include     #endif    //===========================================================================
// 以下程式碼為 Taspect Class 之宣告
// Taspect Class 主要為印出星號
//===========================================================================
class Taspect
{
  private:
  public:
  void aspect(int iaspect,TMemo *Memo);
};
妳可以把所有的程式碼都寫成Function(寫在同一個檔案裡面.cpp),這樣以後只要有這檔案就可以馬上運用了!也可以把下面的Function,Copy到自己的Function裡面,方便自己用!(做成自己的函式庫) 應用範例:http://delphi.ktop.com.tw/topic.php?topic_id=64717 發表人 - cashyy 於 2005/05/13 03:22:19 發表人 - cashyy 於 2005/05/13 04:15:51
KENI_LIN
中階會員


發表:86
回覆:267
積分:90
註冊:2004-05-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-05-14 17:50:16 IP:61.64.xxx.xxx 未訂閱
引言: 我想我把我比較會的C寫好後..exe檔 經由BCB的介面來去執行它 然後出來的結果秀在BCB上
另一個最簡單的做法,再Button物件下鍵入 WinExec("e7.exe",NULL); 其中e7.exe就是你說的"會的C寫好後..exe檔",但是要把這個執行檔跟你的Project放在同一個目錄,或是設路徑將"e7.exe"改為"c:\\e7.exe,去呼叫它,但就要把這個執行檔copy到C槽底下. 寒窗苦讀十年書;只待今朝狀元時!~~ ︵ / / ︵ ( ∩ ∩ ) ○ ︶ ○ Keni Lin
------
Keni Lin
biller
一般會員


發表:12
回覆:4
積分:3
註冊:2004-08-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-05-14 22:36:00 IP:202.111.xxx.xxx 未訂閱
我觉得用windows API比较方便
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-05-16 22:02:31 IP:218.162.xxx.xxx 未訂閱
我目前只用了下面這個方法來做,最近實在忙到我喘不過氣, 所以就暫時停止了學習 抽了空剛剛草草的寫了一下 void __fastcall TForm1::Button1Click(TObject *Sender) { WinExec("e7.exe",NULL); } C的程式也放到同目錄下了,不過沒有反應 這程式是把space.txt內的空白通通刪除只剩一個 然後再秀出來結果(沒有回存) http://www.cyut.edu.tw/~s9127073/e7.exe http://www.cyut.edu.tw/~s9127073/space.txt 不過配合了WinExec("e7.exe",NULL);就沒有結果出現了 其他大大的方法等到我有空時再來研究,目前想先試這個,謝謝
KENI_LIN
中階會員


發表:86
回覆:267
積分:90
註冊:2004-05-31

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-05-16 22:31:39 IP:210.80.xxx.xxx 未訂閱
引言: 抽了空剛剛草草的寫了一下 void __fastcall TForm1::Button1Click(TObject *Sender) { WinExec("e7.exe",NULL);//e7.exe是給妳參考,不是真的一定要叫e7.exe } C的程式也放到同目錄下了,不過沒有反應
沒有反應是因為妳的執行檔名應該不是叫e7.exe;如紅字所示,把以上程式的e7.exe,改為妳程式的檔名.exe,並記的把妳程式的執行檔和BCB新建的程式目錄放在一起,這樣應該就可以開啟了! 寒窗苦讀十年書;只待今朝狀元時!~~ ︵ / / ︵ ( ∩ ∩ ) ○ ︶ ○ Keni Lin
------
Keni Lin
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-05-16 22:35:34 IP:218.162.xxx.xxx 未訂閱
我早已經改了啊^^ 還是沒有任何的反應呢?
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-05-16 23:36:15 IP:219.137.xxx.xxx 未訂閱
Miki-lion 您好:    給妳一個範例,請到下列位址下載一個 .zip 格式的壓縮檔,將壓縮檔內的兩個檔案解壓縮至妳正在測試那支程式的相同目錄內http://delphi.ktop.com.tw/topic.php?TOPIC_ID=71137 壓縮檔非常小,內有兩個檔案: go.bat 165個byte cr.txt 2個byte 然後將下列敘述複製到妳的測試程式內試試看:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // 下列 ProgPath 為取得妳現在正在執行這支程式的存放路徑
    AnsiString ProgPath = ExtractFilePath(ParamStr(0));
    AnsiString prog="go.bat";  // 欲執行的批次檔名稱
    AnsiString parm = "temp.txt";  // 欲存放 e7.exe 程式輸出結果的文字檔名稱
    // 下列之 SW_HIDE 參數為不顯示執行時的 DOS 視窗,若想顯示則改成 SW_SHOW
    ShellExecute(Application->Handle, "open", prog.c_str(), parm.c_str(), ProgPath.c_str(), SW_HIDE);
}
前述兩個檔案的說明如下: 1. 因為 e7.exe 是 console 程式,且資料是輸出到 cout,所以用導向的方式將輸出資料轉存到指定的檔案內。 2. 因為 e7.exe 輸出資料後尚需按 Enter 鍵才會結束程式,因此亦使用導向方式將模擬 Enter 鍵的換行字元傳給 e7.exe。 3. 基於以上動作,故使用批次檔來處理較為合宜,批次檔名稱為 go.bat。 4. 為便於使用第 2 項所述之換行字元,故將換行字元 ASCII Code 13, 10 (0x0D, 0x0A) 寫成一個文字檔,文字檔名稱為 cr.txt。 go.bat 內容如下: @echo off if "%1" == "" goto err e7 > %1 < cr.txt goto end :err echo usage: echo go output_file_name echo. echo example: echo go temp.txt echo. :end cr.txt 檔內容僅有 ASCII Code 13, 10 兩個碼,因為是非可視字元,故無法貼上來。 發表人 - RedSnow 於 2005/05/17 00:02:11
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-05-17 00:10:48 IP:218.162.xxx.xxx 未訂閱
我都照做了~可是依然沒有反應 我想可能是我誤會你的意思了 我新開了一個form,將你個程式碼加到button1裡面 再將go.bat和cr.txt放在同一個資料夾內 我的程式和要處理的文字檔需要放再同一個資料夾嗎?(我也有放了) 結果會回存到新開的temp.txt嗎? 因為我看他會產生這個檔案 不過他依然是空白(cr.txt內容也是空白)
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-05-17 01:37:17 IP:219.137.xxx.xxx 未訂閱
我是依據妳那支名為 e7.exe 的程式與名為 space.txt 的檔案來寫的,妳可以檢查一下它們是否也都放在同一目錄內?另外妳提到 cr.txt 檔案是空的,那是因為該檔案內僅有一組換行字元,故看起來像是沒有資料,這是正常的。    如果妳確認前述程式與檔案也都放在同一目錄,但是仍無法產生有內容的 temp.txt 檔案,那麼請妳協助我做下列處理:    先將 go.bat 檔案內容修改如下: @echo off cls ver dir e7.exe space.txt /b attrib temp.* if "%1" == "" goto err echo on e7 > %1 < cr.txt dir "%1" pause goto end :err echo usage: echo go output_file_name echo. echo example: echo go temp.txt echo. :end 再將我前一篇寫到的 SW_HIDE 處改成 SW_SHOW,然後再執行妳的程式測試一下,並將顯示出來的畫面複製下來貼上來,我看看能不能找出問題來? 發表人 - RedSnow 於 2005/05/17 01:44:31
KENI_LIN
中階會員


發表:86
回覆:267
積分:90
註冊:2004-05-31

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-05-17 10:29:31 IP:192.72.xxx.xxx 未訂閱
我試過了,應該可以用,妳加入紅字的部分看看:
 
//---------------------------------------------------------------------------
#include 
#include 
#pragma hdrstop    #include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------    void __fastcall TForm1::Button1Click(TObject *Sender)
{
 WinExec("UEDIT32.EXE",NULL);
}
//---------------------------------------------------------------------------    void __fastcall TForm1::Button2Click(TObject *Sender)
{
 WinExec("C:\\Program Files\\UltraEdit\\UEDIT32.EXE",NULL);
}
//---------------------------------------------------------------------------
但這個WinExec方式比較不靈敏,有時候要按"兩次"Button才能執行! 寒窗苦讀十年書;只待今朝狀元時!~~ ︵ / / ︵ ( ∩ ∩ ) ○ ︶ ○ Keni Lin
------
Keni Lin
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-05-17 22:03:23 IP:61.225.xxx.xxx 未訂閱
已經試出來了~好感激你喔~~^^ 不過我是希望除了把結果回存到temp.txt外~ 還能秀在bcb上面的Edit或是memo上面~~ BCB好好玩喔~不過學校都沒教~~嗚 米奇獅仔~^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-05-17 23:33:55 IP:200.226.xxx.xxx 未訂閱
引言:不過我是希望除了把結果回存到temp.txt外~ 還能秀在bcb上面的Edit或是memo上面~~
那麼妳就在做完前述動作後,再加上 Memo 物件的讀檔動作即可,參考下列作法:
AnsiString ProgPath = ExtractFilePath(ParamStr(0));
AnsiString prog = "go.bat";
AnsiString parm = "temp.txt";
AnsiString tmpFile = ProgPath parm;
if(FileExists(tmpFile)){  // 如果已經存在 temp.txt 這個檔案
    DeleteFile(tmpFile);  // 那就先刪除掉舊的 temp.txt 檔
}    Memo1->Clear();  // 先清除 Memo 物件內容    ShellExecute(Application->Handle, "open", prog.c_str(), parm.c_str(), ProgPath.c_str(), SW_HIDE);    Sleep(1000);  // 暫停一秒鐘緩衝一下,讓檔案確實完成寫入動作    while (true) {  // 執行迴圈直到檔案產生完畢
    if(FileExists(tmpFile)){  // 如果檔案確實存在
        Memo1->Lines->LoadFromFile(tmpFile); // 讀取檔案內容給 Memo 物件
        break;  // 跳出 while 迴圈
    }
    Application->ProcessMessages(); // 避免執行迴圈時,整個程式被咬住而影響其它部分的操作
}
如果要確保程式能正確執行,或許還要加上一些最佳化處理,以避免一些預期外的狀況發生,例如:萬一 temp.txt 未能正確產生,應該如何結束迴圈....等等。
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-05-18 00:02:56 IP:61.225.xxx.xxx 未訂閱
將程式碼給物件memo後~編譯也成功了~ 不過並沒有把temp.txt的內容給它耶~~就停在那了..嗚嗚~ 米奇獅仔~^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#17 引用回覆 回覆 發表時間:2005-05-18 01:04:18 IP:219.137.xxx.xxx 未訂閱
Miki-lion 妳好:    妳有將 go.bat 的內容改回原來的嗎?前一次要妳修改的是作測試用的,會有顯示 DOS 視窗及暫停的動作,妳要正式使用時,還是要改回第一次寫給妳的那些內容才行,要不然妳就必須切換到那個 DOS 視窗去,然後按下 Enter 鍵才能讓它繼續執行。 發表人 - RedSnow 於 2005/05/18 01:08:15
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#18 引用回覆 回覆 發表時間:2005-05-18 01:13:45 IP:61.225.xxx.xxx 未訂閱
我有耶~~2個都試了~~第一個也可以產生內容在temp.txt了 另外我也想學看看批次檔~要看甚麼樣的語法呢? 米奇獅仔~^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#19 引用回覆 回覆 發表時間:2005-05-18 01:46:27 IP:219.137.xxx.xxx 未訂閱
再給妳另一種處理方式,妳試試看:
AnsiString ProgPath = ExtractFilePath(ParamStr(0));
AnsiString oldDir = GetCurrentDir();
AnsiString cmd = getenv("COMSPEC");
AnsiString prog = "go.bat";
AnsiString parm = "temp.txt";
AnsiString tmpFile = ProgPath parm;
AnsiString cmdline = cmd   " /C "   prog   " "   parm;    bool err = false;    SetCurrentDir(ProgPath);    DeleteFile(tmpFile);
Memo1->Clear();    UINT Result;
DWORD dwExitCode;
STARTUPINFO StartupInfo = {0};
PROCESS_INFORMATION ProcessInfo;    ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.wShowWindow = SW_HIDE;    Result = CreateProcess(NULL, cmdline.c_str(), NULL, NULL, false, 0, NULL, NULL, &StartupInfo, &ProcessInfo);    if (Result) {
    CloseHandle(ProcessInfo.hThread);
    if (WaitForSingleObject(ProcessInfo.hProcess, INFINITE) != WAIT_FAILED) {
        GetExitCodeProcess(ProcessInfo.hProcess,&dwExitCode);
    }
    CloseHandle(ProcessInfo.hProcess);        if(FileExists(tmpFile)){
        Memo1->Lines->LoadFromFile(tmpFile);
    }else{
        err = true;
    }
}else{
    err = true;
}    if(err) ShowMessage(tmpFile   " not found!");    SetCurrentDir(oldDir);
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#20 引用回覆 回覆 發表時間:2005-05-18 13:36:27 IP:61.225.xxx.xxx 未訂閱
還是不行~~一一!!! 依然沒有顯示在memo上 我在想是不是memo物件還需要設定甚麼 我把全部的程式都壓在這裡了~~以免又出錯 http://www.cyut.edu.tw/~s9127073/test.rar 米奇獅仔~^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#21 引用回覆 回覆 發表時間:2005-05-18 14:38:06 IP:218.19.xxx.xxx 未訂閱
我的天啊~來人啊,有誰能幫我叫一部救護車嗎..... 獅仔!妳也太離譜了點吧?妳竟然將我提供的敘述放在 Memo1 的 OnChange 事件裡邊,妳是想要炸自己嗎?妳現在試試看在 Memo 裡邊隨便輸入一個字看看會怎樣?嘿嘿~在妳試之前,我可先提醒妳喔,不要暈倒....。 等妳回過神來之後,請將 Memo1 OnChange 事件的內容刪除掉,然後將我給妳的那些範例敘述放到 Button1 的 OnClick 事件裡,然後再試試看。 發表人 - RedSnow 於 2005/05/18 14:43:49
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#22 引用回覆 回覆 發表時間:2005-05-18 15:00:17 IP:61.225.xxx.xxx 未訂閱
引言: 我的天啊~來人啊,有誰能幫我叫一部救護車嗎..... 獅仔!妳也太離譜了點吧?妳竟然將我提供的敘述放在 Memo1 的 OnChange 事件裡邊,妳是想要炸自己嗎?妳現在試試看在 Memo 裡邊隨便輸入一個字看看會怎樣?嘿嘿~在妳試之前,我可先提醒妳喔,不要暈倒....。 等妳回過神來之後,請將 Memo1 OnChange 事件的內容刪除掉,然後將我給妳的那些範例敘述放到 Button1 的 OnClick 事件裡,然後再試試看。 發表人 - RedSnow 於 2005/05/18 14:43:49
別罵我嘛~~~嗚嗚嗚~~~我弄出來了~~謝謝你 剛剛才完全看懂程式碼~~以後我可以應用你教我的了 謝謝你~~^^(我弄錯的變成視窗炸彈了一一!!!) 米奇獅仔~^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#23 引用回覆 回覆 發表時間:2005-05-18 15:09:49 IP:218.19.xxx.xxx 未訂閱
呵呵~收到警惕作用啦?那二十大板就免了....。 不過我還是蠻好奇的,如果妳可以接受我提供的那些敘述,那又為何要用這種呼叫外部程式的方式來處理呢?e7.exe 那支程式所處理的動作,如果直接寫在同一支 BCB 程式裡,應該會方便很多的,難道是作業要求?
Miki-lion
中階會員


發表:90
回覆:180
積分:54
註冊:2005-04-24

發送簡訊給我
#24 引用回覆 回覆 發表時間:2005-05-18 15:32:34 IP:61.225.xxx.xxx 未訂閱
一開始我就有說了啊~我比較會C語言~BCB根本不懂~只會照著書上的學 所以與其慢慢的學BCB~到不然寫C給BCB來呼叫~(因為我想作一個介面出來) 不是作業啦~~是明年要交的專題~不過我的專題老師都不會~ 我只能自己慢慢學~連進度目標都是我自己定的~好辛苦.一一!!! 到最後是要做出一個能將網頁減肥的程式(刪空白,TAB,換行,多行取代等等) 最後會做到甚麼的程度~我也不知道~~老師只說了個大概而已 下面這個是大約程式要有的功能~刪除部分我都已經個別做好了 http://www.cyut.edu.tw/~s9127073/miki_part.jpg 插入跟取代有點難度還沒做~~女生還是唸藝術跟設計的好...>< 米奇獅仔~^^
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#25 引用回覆 回覆 發表時間:2005-05-18 16:43:17 IP:218.19.xxx.xxx 未訂閱
如果妳們的專題沒有限制使用工具與範圍的話,我提供一些資料供妳參考: 1. 妳們的專題看起來大都與字串資料有關,而 BCB 的 AnsiString 有提供豐富的各類處理函式,妳不妨查看一下 AnsiString 的相關說明,同時下列文章也可以參考一下: http://delphi.ktop.com.tw/topic.php?topic_id=20416 2. BCB 有一個名為 StringReplace() 的字串代換函式蠻好用的,針對妳們要刪除換行符號、代換空白字元、代換 Tab 字元.....等動作,可很方便的就完成,請參考下列文章: 如何在一個文章中找每一段的第一個字,以及處理換行後的空白 http://delphi.ktop.com.tw/topic.php?topic_id=70525 Split () 分割字串函數 http://delphi.ktop.com.tw/topic.php?topic_id=70382 祝妳撰寫專題順利!
系統時間:2024-05-03 0:17:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!