2011-04-20 87 views
1

Backstory:我正在創建一個擴展遊戲製作工具,一個流行的遊戲開發套件。擴展是一個DLL,它爲內置的腳本語言增加了新的功能,但是用C或Pascal或其他語言編寫。通常,它用於允許遊戲使用外部庫。無法添加項目到Win32列表框控件

在我的情況下,我添加了FMOD支持。這不相關。與此相關的是,爲了進行調試,我還添加了一個對話框,在運行時顯示該對話框,顯示我的庫的內部狀態。我需要這個窗口的幫助。在今天之前我已經完全沒有使用原始的Win32表單編程(.NET WinForms 4eva),所以我可能會做一些無能爲力的事情。

無論如何。我有一個列表框,我想將其添加到列表框中,但是當我嘗試添加它們時,它會失敗。我的代碼:

extern DebugDialog * debugDialog; 

DebugDialog::DebugDialog(HWND owner, HINSTANCE hInst) { 
    this->hWnd = 0; 

    HWND hWnd = CreateDialogParam(hInst, 
         MAKEINTRESOURCE(IDD_DEBUGDIALOG), 
         owner, 
         DialogProc, 
         reinterpret_cast<LPARAM>(this)); 

    ShowWindow(hWnd, SW_SHOW); 

} 

DebugDialog::~DebugDialog(void) { 
    DestroyWindow(this->getHWnd()); 
    debugDialog = NULL; 
} 

BOOL CALLBACK DebugDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 
    DebugDialog * self; 

    if(message == WM_INITDIALOG) { 
     self = reinterpret_cast<DebugDialog *>(lParam); 
     self->hWnd = hWnd; 
     SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self)); 
    } else { 
     self = reinterpret_cast<DebugDialog*>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); 
    } 

    if(self) { 
     return self->HandleMessage(message, wParam, lParam); 
    } else { 
     return FALSE; 
    } 
} 


BOOL DebugDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    switch(uMsg) { 
     case WM_INITDIALOG: 
      MessageBox(this->getHWnd(), "Okay!", "Debug", 0); 
      return TRUE; 

     case WM_COMMAND: 
      switch(LOWORD(wParam)) { 
       case ID_CLOSE: 
       case IDOK: 
       case IDCANCEL: 
        delete this; 
        return TRUE; 
       default: 
        return FALSE; 
      } 
      return TRUE; 
    } 

    return false; 
} 

void DebugDialog::loadedSound(FMODGM_Sound * sound) { 
    HWND hwndList = GetDlgItem(this->getHWnd(), IDC_LIST); 

    LPARAM sound_text = (LPARAM)sound->file.c_str(); 

    LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text); 
    SendMessage(hwndList, LB_SETITEMDATA, lResult, (LPARAM)sound); 

} 

DebugDialog是一個簡單的類,它封裝了窗口,讓我從外面操縱它。基本上,在一些其他的點,我這樣做:

debugWindow = new DebugDialog(owner, hInst); 

接着,當我執行,做有趣的事情,我這樣做:

FMODGM_Sound * sound = ...; 

if(debugWindow) debugWindow->loadedSound(sound); 

loadedSound,我將消息發送到列表框中說:「嘿,這是一個項目,繼續前進,並添加。」,並沒有返回錯誤。但是,它也不會在框中添加任何內容。每次我調用它時,它都會返回0。根據文檔,0表示它添加了一個項目,其索引爲0.但是,該項目不存在。

我有一個理論,爲什麼它不工作。我無法控制Game Maker運行的消息泵,因此如果它做的是任何時髦的東西,我都不知道,也不能更改它。也就是說,對話框的其他所有內容都可以工作,包括移動它,單擊Close按鈕,然後用鼠標在列表框中繪製選框。

有人,請告訴我,我在做什麼可怕的錯誤:(

編輯:有人問起FMODGM_Sound結構,所以這裏是:

struct FMODGM_Sound { 
FMOD::Sound * sound; 
std::vector<FMOD::Channel*> channels; 
    std::string file; 

public: 
    FMODGM_Sound() { 
     sound = NULL; 
    } 
}; 

沒有什麼特別花哨的

+0

GetLastError()會說什麼嗎?提示:假設您使用的是MSVC,您可以在Debug手錶中添加「@err」變量。 – 2011-04-20 08:47:16

+0

@Jonas Gulle,我已經做到了(非常方便:D)。不幸的是,沒有錯誤出現。 – 2011-04-20 19:56:12

+0

如果在SendMessage調用之後的[UpdateWindow(hwndList)](http://msdn.microsoft.com/en-us/library/dd145167%28v=vs.85%29.aspx)會發生什麼? – 2011-04-20 21:59:27

回答

0

您可以顯示FMODGM_Sound結構和文件字段的聲明嗎?

如果替換

會發生什麼
LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text); 

with?

LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, "some constant text"); 
+0

沒有什麼不同。同樣如果(在預感上),我使用'L「來代替一些常量文本。 – 2011-04-20 20:05:52

+0

可能是您的列表框被設計爲「OWNER_DRAWN」?檢查此(從MSDN http://msdn.microsoft.com/en-us/library/bb775181%28v=vs.85%29.aspx):如果列表框具有所有者繪製的樣式但不是LBS_HASSTRINGS樣式,此參數作爲項目數據而不是字符串存儲。您可以發送LB_GETITEMDATA和LB_SETITEMDATA消息來檢索或修改項目數據。 – 2011-04-21 07:23:29

0

將您的DLL編譯爲Unicode版本還是多字節版本?

如果是Unicode,那麼sound_text應該是一個Unicode字符串。我猜這個文件是一個std :: string,所以file.c_str()會返回一個多字節字符串。

+1

根據這個調用:MessageBox(this-> getHWnd(),「Okay!」,「Debug」,0);項目編譯爲MBCS(否則必須發生編譯錯誤:從CHAR轉換爲WCHAR) – 2011-04-20 11:40:01

+0

這是正確的。它被編譯爲Multibyte。這主要是爲了與Game Maker的兼容性,Game Maker的字符串格式是'char *'。 – 2011-04-20 20:01:48

+0

是通過'GetDlgItem(this-> getHWnd(),IDC_LIST)是否正確的HWND;'?我想你應該先驗證一下。 – 2011-04-21 02:18:04

0

我有一個非常類似的問題,並已解決。基本上,你必須把它作爲一個c風格的字符串,而不是(str.c_str())。雖然我是一個完整的新手,但經過Google如何使用它之後,它運行良好。

雖然我使用的代碼提供的功能完全不同於您的代碼,但它可能是一個很好的例子。

int i = res->getInt("ID"); 
    std::string str = boost::lexical_cast<std::string>(i); 
    char *cstr = new char[10]; 
    strcpy_s(cstr, 10, str.c_str()); 
    SendDlgItemMessage(hwnd, IDC_lbList, LB_ADDSTRING, 0, (LPARAM)cstr); 

編輯:哇,我什至沒有看日期。我是一個死靈法師......