本来是 在一个按钮的 单击事件中执行的代码,因为太复杂,运行时会导致出口假死,
所以改用多线程,没改之前运行没问题,改为后 一运行 就会有个 全屏窗口出现在屏幕上(这个窗口正常是不该出现的,)
线程中的代码也没有正常执行。下面是 线程中的 部分代码,请高手帮忙看看是 什么问题 ;CreateThread(nil, 0, @CreatNcList, nil, 0, ID);  //掉用 线程 的 语句   
线程 代码try
      Excel:=CreateOleObject('Excel.Application');
      Excel.visible:=false;
      WorkBook:=CreateOleobject('Excel.Sheet');   except
      ShowMessage('无法打开xls文件,请确认已经安装EXCEL');
      Exit;
   end;   i:=0;
   while i<FormNcList.ListBox_NcFileList.Count do
   Begin
       iRow:=2;
       RowCellName:='';
       RowCellCount:=0;
       WorkSheetsNum:=1;
       WorkBook:= Excel.workBooks.Open(FormNcList.ListBox_NcFileList.Items.Strings[I]);
       //ShowMessage(IntToStr(Excel.Workbooks[1].WorkSheets.Count));
       //ShowMessage(Excel.Workbooks[1].WorkSheets[1].Name);       while (Excel.Workbooks[1].WorkSheets.Count > 0) and (WorkSheetsNum <= Excel.Workbooks[1].WorkSheets.Count) do
       Begin
          if Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Name <> '' then
          Begin
             WorkSheetsName:=Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Name;
             WorkSheetsName:=StringReplace(WorkSheetsName,chr(32),'',[rfIgnoreCase,rfReplaceAll]);
             if CompareText(WorkSheetsName,'NcList') = 0 then
             Begin
                QTY:=StringReplace(Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Cells[1,7].Value,chr(32),'',[rfIgnoreCase,rfReplaceAll]);
                REFDES:=StringReplace(Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Cells[1,8].Value,chr(32),'',[rfIgnoreCase,rfReplaceAll]);
                if CompareText(REFDES,'REFDES') = 0 then
                Begin
                   while Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Cells[iRow,8].Value <> '' do
                   Begin
                      RowCellName:=RowCellName + Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Cells[iRow,8].Value;
                      //Row:= Row + Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Cells[iRow,7].Value;
                      iRow:=iRow + 1;
                   End;
                End;                if CompareText(QTY,'QTY') = 0 then
                Begin
                   while iRow >= 2 do
                   Begin
                      RowCellCount:=RowCellCount + Excel.Workbooks[1].WorkSheets[WorkSheetsNum].Cells[iRow,7].Value;
                      iRow:=iRow - 1;
                   End;
                End;
                ShowMessage(IntToStr(RowCellCount));
                ShowMessage(RowCellName);
                Break;
             End;
          End;
          WorkSheetsNum:=WorkSheetsNum+1;
       End;
       Excel.WorkBooks[1].Close(False,FormNcList.ListBox_NcFileList.Items.Strings[I]);    //取文件名退出

解决方案 »

  1.   

    在线程函数中:
    CoInitialize(nil);
    你的线程代码
    CoUnInitialize另外,在线程中访问界面要同步,比如ShowMessage.可以自己写个MyShowMessage,在线程中调用它就行了:
    procedure MyShowMessage(const Msg: string);
    begin
      SendMessage(Form1.Handle, WM_USER + 123, 0, LPARAM(PChar(Msg)));
    end;然后Form1响应WM_USER + 123消息:
    type
      TForm1 = class(TForm)
      ...
      private
        procedure MyMsg(var M: TMessage); message WM_USER + 123;
      end;procedure TForm1.MyMsg(var M: TMessage);
    begin
      ShowMessage(PChar(M.LParam));
    end;
      

  2.   

    CoInitialize(nil);
    你的线程代码
    CoUnInitialize        加入这两句代码会出错,说  E2003 Undeclared identifier: 'CoInitialize'另外,在线程中访问界面 时 可以不同步吗,我这里是有一个线程(除主线程外)
      

  3.   

    1. uses ActiveX;
    2. 要同步,你那个全屏窗口说不定就是ShowMessage弹的。
      

  4.   

    全屏窗口,就是ShowMessage引起的,改成同步
      

  5.   

    因为ShowMessage实际上就是要创建一个form窗体,然后showmodal显示出来,线程运行到这里当然就出错了访问界面/VCL要用同步 (有时可以不用,但要看是访问是什么东西了)
      

  6.   

    谢谢各位,全屏窗口 果然 是ShowMessage弹的,我把所有 ShowMessage 都注释掉就不再弹出了 !!!
      

  7.   

    谢谢 各位全屏窗口果然是ShowMessage引起的,把 所以 ShowMessage 注释掉就没问题了。