Installshield12自定義對話框實現定時功能的探索

最近想在IS12製作的安裝包的安裝界面上實現一種定時功能:

當顯示一個界面後,即開始計時,定時10秒到時如果用戶還沒有任何操作則默認是NEXT,進入下一步,10秒之前用戶可做任何選擇。

查了help文檔中和time有關的所有搜索條目都沒有看到IS12與定時有關的任何函數,只有Delay(秒);安裝界面都是一個SD函數實現的,這裏爲了修改界面的動作,使用的是自定義對話框,由於只是希望在原有對話框的基礎上多一個10-0的倒數顯示,只要添加一個Text,所以這裏在use interface的Dialog中,選擇一個已定義的對話框,點擊Edit Dialog layout,添加一個Text Area,再右鍵Clone這個對話框,將複製的dialog rename爲MyDlg,在Installscript中添加自定義對話框MyDlg的腳本mydlg.rul

這裏使用的是EzDefineDialog ( szDialogName, szDLLName, szDialogID, nDialogID ); 定義這個對話框,WaitOnDialog ( szDlgName );顯示這個對話框,我查了很多資料,都是使用這個方式,所以我也採用這種方式。

對於定時功能,我做了大概以下3種探索:

1.使用Delay()函數

在WaitOnDialog 的default的返回值的處理中,使用Delay()來定時,

for nCount = 10 downto 1
     Delay(1);//延時一秒 
      // Convert the number to a string.  
      nResult = NumToStr (strCount, nCount);
      CtrlSetText( DLG_MYDLG, TIMETEXT, strCount);
endfor;

在for循環中,延時一秒則更新一下時間的顯示,存在的問題,Delay這種方式本來就是阻塞了,程序會一直停留在這裏無法響應任何其他的操作,可以正確的顯示窗口,也可以看到時間在倒數,但是就是不能響應其他的操作,即其他的操作必需要在10後才能得到相應,failed

2.Delay(1)+Sendmessage

由於是For循環阻塞了消息循環,所以就想到使用Sendmessage的方式來發送messge,

WaitOnDialog Return Values 

Return Value

Description

dialog control ID

The ID of the dialog control that received the WM_COMMAND message.

IDCANCEL (2)

This message is received as a signal that the dialog box is about to close.

DLG_ERR (-1)

This message is received if any errors occurred.

DLG_INIT (-100)

This message is received immediately before the dialog box is displayed.

help中的文檔關於WaitOnDialog的返回值的第一項dialogControlID,是接收界面上的控件的WM_COMMAND message,於是發送

//延遲一秒之後,顯示時間
 Delay(1);//延時一秒
// Convert the number to a string. 
nCount= nCount-1;
nResult = NumToStr (strCount, nCount);
CtrlSetText( DLG_MYDLG,TIMETEXT, strCount);
       
hDlg = CmdGetHwndDlg(DLG_MYDLG);     
if nCount = 0 then
        //當計時結束時,發送NEXT信息   
        SendMessage (hDlg, WM_COMMAMD, RES_PBUT_NEXT, 0);
      else 
        //倒計時沒有到10秒時,依然send message to the time ctrl 
        SendMessage (hDlg, WM_COMMAMD, TIMETEXT, 0);
endif;

但是總是不正確,WaitOnDialog沒有響應Sendmessage的任何消息,而只能顯示界面上的點擊等動作,我懷疑是不是IS中的Sendmessage用的不對啊,help中sendmessage的例子SendMessage (nHwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);也有試過都可以成功的。於是就想寫個dll來像這個DLG發送一個message。

3.DLL實現定時器,並向自定義對話框發送定時10秒到的message

DLL實現:

void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)
{
 g_nCount--;
 SetDlgItemInt(g_hDlg,g_nID,g_nCount,TRUE);
 if ( g_nCount == 0 )
 {
  KillTimer(g_hDlg,1);
  SendMessage(g_hDlg,WM_COMMAND,g_nIDBtn,0);
  DestroyWindow( g_hDlg );

 }
}


// This is export API
COUNTDOWN_API  int  RegisterCountdown(HWND hDlg,int nIDDlgItem,int nIDBtn)
{
 SetDlgItemText(hDlg,nIDDlgItem,"10");
 g_hDlg = hDlg;
 g_nID = nIDDlgItem;
 g_nIDBtn = nIDBtn;
 SetTimer(hDlg,1,1000,TimerProc );
 
 return 1;
}

在Installscript中調用這個API

            nResult=UseDLL(SUPPORTDIR^"countdown.dll");
             if nResult=0 then
              MessageBox("動態庫加載成功",INFORMATION);
              hDlg = CmdGetHwndDlg(DLG_MYDLG);
              nResult=RegisterCountdown(hDlg,TIMETEXT,RES_PBUT_NEXT);
           else
              MessageBox("動態庫加載失敗",INFORMATION);
              abort;
           endif;
時間到時,依然不能響應NEXT的動作。

但是在MFC AP中調用這個函數則可以成功,響應button的動作。

於是,我沒轍了~~

看到有人使用:

hProgressBar = CtrlGetDlgItem(DLGNAME,CmdGetHwndDlg(DLGNAME),PROGRESSBAR_ID);
SendMessage(hProgressBar,PBM_SETPOS,20,0);

的方法,獲取到自定義的進度條的句柄,進而給這個進度條控件直接發送一些消息,可以成功,但是用的是2010,在IS12中CtrlGetDlgItem不被識別,也沒有辦法試一下,因爲我們只有IS12,不知道誰有2010可以試一下這個方法。

這次失敗主要是WaitOnDialog 阻塞了這些消息,但不知道大家都還有什麼好的方法,在IS中可以實現這個功能,請給我留言哦~~謝謝~~

 

 

發佈了27 篇原創文章 · 獲贊 9 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章