發表文章

目前顯示的是 10月, 2008的文章

BCB 使用Thread 後產生的錯誤 Canvas does not allow drawing

圖片
下圖是我在BCB使用中Thread後,原本相安無事的程式碼,突然出現的例外錯誤"Canvas does not allow drawing"。求救估狗大神後,說是在子執行緒中使用ShowMessage方法,會讓部分底層元件出現問題。 解決的方法就是呼叫Win32API,或是進行同步化,下面簡略的介紹以Win32API作轉換。 其實在子執行緒中使用ShowMessage,也不見得會有Exception產生,有時可能沒事情(機率很小),有時可能只跳出一個放大的Dialog且沒有按鈕可以結束它。 解決方案-Win32API 這個解決方案只能使用於小型的程式,大型程式可能會顯得礙手礙腳。 若你在個人的程式庫,十分愛用ShowMessage作為對使用者顯示訊息的手段,建議現在就著手修改為其他方式(有學過Java的朋友,可以考慮改為丟出Exception),因為本方案並不能解決你的問題。 本解決方案就是將你的視窗類別中多加一個ShowMessage方法。若你的主式窗名稱是TForm1,則將要加入的函式寫成下面這樣。 void TForm1::ShowMessage(const AnsiString &str) { // 一定要有雙冒號(::)代表存取Scope最外面部的MessageBox函式 ::MessageBox(NULL, str.c_str(), "Dialog Title", MB_OK); } Win32API的MessageBox參數簡易解說 NULL 是方便行事,其是也可以改成的你視窗的handle屬性。 str.c_str() 是將因為MessageBox支援的型態不是AnsiString,而是char*。 "Dialot Title" 是你可以改的顯示視窗標題(Title)。 MB_OK 顯示的按鈕種類,請查閱BCB的Help取得更多的種類說明。 然後記得在主視窗類別的.h檔也要加入對應的宣告。 void ShowMessage(const AnsiString&); 放在類別的private、protected或public區域都行,視你的應用而定。