Results 1 to 10 of 10

Thread: windows code troubling Qt

  1. #1
    Join Date
    Jan 2006
    Posts
    667
    Thanks
    10
    Thanked 80 Times in 74 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default windows code troubling Qt

    Hi,

    I am trying to read contents from Windows Address Book using the following code.

    Qt Code:
    1. #include <list>
    2. using namespace std;
    3.  
    4. WABImporter::WABImporter(ContactDetails *cd,QWidget *parent) : QDialog(parent),contactDetails(cd)
    5. {
    6. setAttribute(Qt::WA_DeleteOnClose);
    7. setWindowTitle(tr("Windows Address Book"));
    8.  
    9. cWAB = new CWAB("");//This object has no Qt code and is used to read from windows address book
    10.  
    11. contactData = new ContactData(this);
    12.  
    13. splitter = new QSplitter(Qt::Horizontal,this);
    14.  
    15. listWidget = new QListWidget(this);
    16.  
    17. viewMode = new ViewMode(this);
    18. cardArea = new QScrollArea(this);
    19. cardArea->setMinimumWidth(300);
    20. cardArea->setWidget(viewMode);
    21. cardArea->setWidgetResizable(true);
    22. cardArea->setFrameStyle(QFrame::Box|QFrame::Plain);
    23.  
    24. splitter->addWidget(listWidget);
    25. splitter->addWidget(cardArea);
    26.  
    27. importCurrentButton = new QPushButton(tr("&Import current contact"),this);
    28. importAllButton = new QPushButton(tr("&Import &All"),this);
    29. cancelButton = new QPushButton(tr("&Cancel"),this);
    30.  
    31. connect(importCurrentButton,SIGNAL(pressed()),this,SLOT(importCurrent()));
    32. connect(importAllButton,SIGNAL(pressed()),this,SLOT(importAll()));
    33. connect(cancelButton,SIGNAL(pressed()),this,SLOT(close()));
    34.  
    35. QHBoxLayout *hLay1 = new QHBoxLayout;
    36. hLay1->addStretch(1);
    37. hLay1->addWidget(importCurrentButton);
    38. hLay1->addWidget(importAllButton);
    39. hLay1->addWidget(cancelButton);
    40.  
    41. QVBoxLayout *mainLayout = new QVBoxLayout(this);
    42. mainLayout->addWidget(splitter);
    43. mainLayout->addLayout(hLay1);
    44.  
    45. setLayout(mainLayout);
    46. setMinimumSize(640,480);
    47.  
    48. populateContactsList();
    49. }
    50.  
    51. WABImporter::~WABImporter()
    52. {
    53. cWAB->ClearWABLVContents();
    54. delete cWAB;//This crashes the application
    55. }
    56.  
    57. void WABImporter::populateContactsList()
    58. {
    59. list<string> contactsList;
    60. if(cWAB->LoadWABContents(contactsList)){
    61. list<string>::iterator listIterator;
    62. for(listIterator = contactsList.begin(); listIterator != contactsList.end(); ++listIterator){
    63. listWidget->addItem(QString::fromStdString(*listIterator));
    64. }
    65. }
    66. }
    To copy to clipboard, switch view to plain text mode 

    There is a menu option, clicking on which will open a dialog box and all the windows contacts are listed there. When I close this dialog the application crahes in

    qeventdispatcher_win.cpp

    Qt Code:
    1. Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin,
    2. UINT wMsgFilterMax, UINT wRemoveMsg)
    3. {
    4. QT_WA({ return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } ,
    5. { return PeekMessageA(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); });//Crashes here
    6. }
    To copy to clipboard, switch view to plain text mode 

    Another very strange thing is that it crahses only when I put a break point in the destructor i.e. delete cWAB and try to debug from there.

    Otherwise, when I close the dialog, nothing happens but crashes when I close the main application window.

    The main application window crahes in qwidget.cpp

    Qt Code:
    1. void QWidgetPrivate::hide_helper()
    2. {
    3. Q_Q(QWidget);
    4. if ((q->windowType() == Qt::Popup))
    5. qApp->d_func()->closePopup(q);
    6.  
    7. // Move test modal here. Otherwise, a modal dialog could get
    8. // destroyed and we lose all access to its parent because we haven't
    9. // left modality. (Eg. modal Progress Dialog)
    10. if (q->isModal())
    11. QApplicationPrivate::leaveModal(q);
    12.  
    13. #if defined(Q_WS_WIN)
    14. if (q->isWindow() && !(q->windowType() == Qt::Popup) && q->parentWidget()
    15. && !q->parentWidget()->isHidden() && q->isActiveWindow())
    16. q->parentWidget()->activateWindow(); // Activate parent
    17. #endif
    18.  
    19. q->setAttribute(Qt::WA_Mapped, false);
    20. hide_sys();//CRASHES HERE
    21.  
    22. bool wasVisible = q->testAttribute(Qt::WA_WState_Visible);
    23.  
    24. if (wasVisible) {
    25. q->setAttribute(Qt::WA_WState_Visible, false);
    26.  
    27. }
    To copy to clipboard, switch view to plain text mode 

    Please Help!

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Quote Originally Posted by munna View Post
    delete cWAB;//This crashes the application
    So, what do you have there?

  3. #3
    Join Date
    Jan 2006
    Posts
    667
    Thanks
    10
    Thanked 80 Times in 74 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Here it is

    Header File

    Qt Code:
    1. class CWAB
    2. {
    3.  
    4. public:
    5.  
    6. CWAB(string fileName);
    7. ~CWAB();
    8.  
    9. bool LoadWABContents(list<string> &contactsList);
    10. void ClearWABLVContents();
    11.  
    12. private:
    13.  
    14. BOOL m_bInitialized;
    15. HINSTANCE m_hinstWAB;
    16. LPWABOPEN m_lpfnWABOpen;
    17. LPADRBOOK m_lpAdrBook;
    18. LPWABOBJECT m_lpWABObject;
    19.  
    20. // Cache Proparray of currently selected item in the list view
    21. LPSPropValue m_lpPropArray;
    22. ULONG m_ulcValues;
    23.  
    24. // Cache entry id of currently selected item in the listview
    25. SBinary m_SB;
    26.  
    27. map<int,void *> contactsMap;
    28.  
    29. void FreeProws(LPSRowSet prows);
    30. //HRESULT HrGetWABTemplateID(ULONG ulObjectType, ULONG *lpcbEID, LPENTRYID * lppEID);
    31. };
    To copy to clipboard, switch view to plain text mode 

    CPP File

    Qt Code:
    1. CWAB::CWAB(string fileName)
    2. {
    3. // Here we load the WAB Object and initialize it
    4. m_bInitialized = FALSE;
    5. m_lpPropArray = NULL;
    6. m_ulcValues = 0;
    7. m_SB.cb = 0;
    8. m_SB.lpb = NULL;
    9.  
    10. {
    11. TCHAR szWABDllPath[MAX_PATH];
    12. DWORD dwType = 0;
    13. ULONG cbData = sizeof(szWABDllPath);
    14. HKEY hKey = NULL;
    15.  
    16. *szWABDllPath = '\0';
    17.  
    18. // First we look under the default WAB DLL path location in the
    19. // Registry.
    20. // WAB_DLL_PATH_KEY is defined in wabapi.h
    21. //
    22. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
    23. RegQueryValueEx( hKey, L"", NULL, &dwType, (LPBYTE) szWABDllPath, &cbData);
    24.  
    25. if(hKey) RegCloseKey(hKey);
    26.  
    27. // if the Registry came up blank, we do a loadlibrary on the wab32.dll
    28. // WAB_DLL_NAME is defined in wabapi.h
    29. //
    30. m_hinstWAB = LoadLibrary( (lstrlen(szWABDllPath)) ? szWABDllPath : WAB_DLL_NAME );
    31. }
    32.  
    33. if(m_hinstWAB)
    34. {
    35. // if we loaded the dll, get the entry point
    36. //
    37. m_lpfnWABOpen = (LPWABOPEN) GetProcAddress(m_hinstWAB, "WABOpen");
    38.  
    39. if(m_lpfnWABOpen)
    40. {
    41. HRESULT hr = E_FAIL;
    42. WAB_PARAM wp = {0};
    43. wp.cbSize = sizeof(WAB_PARAM);
    44. wp.szFileName = (LPSTR) (LPCTSTR) fileName.c_str();
    45.  
    46. // if we choose not to pass in a WAB_PARAM object,
    47. // the default WAB file will be opened up
    48. //
    49. hr = m_lpfnWABOpen(&m_lpAdrBook,&m_lpWABObject,&wp,0);
    50.  
    51. if(!hr)
    52. m_bInitialized = TRUE;
    53. }
    54. }
    55. }
    56.  
    57.  
    58. // Destructor
    59.  
    60. CWAB::~CWAB()
    61. {
    62. if(m_SB.lpb)
    63. LocalFree(m_SB.lpb);
    64.  
    65. if(m_bInitialized)
    66. {
    67. if(m_lpPropArray)
    68. m_lpWABObject->FreeBuffer(m_lpPropArray);
    69.  
    70. if(m_lpAdrBook)
    71. m_lpAdrBook->Release();
    72.  
    73. if(m_lpWABObject)
    74. m_lpWABObject->Release();
    75.  
    76. if(m_hinstWAB)
    77. FreeLibrary(m_hinstWAB);
    78. }
    79. }
    80.  
    81. bool CWAB::LoadWABContents(list<string> &contactsList)
    82. {
    83. ULONG ulObjType = 0;
    84. LPMAPITABLE lpAB = NULL;
    85. //LPTSTR * lppszArray=NULL;
    86. //ULONG cRows = 0;
    87. //LPSRowSet lpRow = NULL;
    88. LPSRowSet lpRowAB = NULL;
    89. LPABCONT lpContainer = NULL;
    90. int cNumRows = 0;
    91. //int nRows=0;
    92.  
    93. HRESULT hr = E_FAIL;
    94.  
    95. ULONG lpcbEID;
    96. LPENTRYID lpEID = NULL;
    97.  
    98. // Get the entryid of the root PAB container
    99. //
    100. hr = m_lpAdrBook->GetPAB( &lpcbEID, &lpEID);
    101.  
    102. ulObjType = 0;
    103.  
    104. // Open the root PAB container
    105. // This is where all the WAB contents reside
    106. //
    107. hr = m_lpAdrBook->OpenEntry(lpcbEID,
    108. (LPENTRYID)lpEID,
    109. NULL,
    110. 0,
    111. &ulObjType,
    112. (LPUNKNOWN *)&lpContainer);
    113.  
    114. m_lpWABObject->FreeBuffer(lpEID);
    115.  
    116. lpEID = NULL;
    117.  
    118. if(HR_FAILED(hr)){
    119. if ( lpContainer )
    120. lpContainer->Release();
    121. if ( lpAB )
    122. lpAB->Release();
    123.  
    124. return false;
    125. }
    126.  
    127. // Get a contents table of all the contents in the
    128. // WABs root container
    129. //
    130. hr = lpContainer->GetContentsTable( 0,&lpAB);
    131.  
    132. if(HR_FAILED(hr)){
    133. if ( lpContainer )
    134. lpContainer->Release();
    135.  
    136. if ( lpAB )
    137. lpAB->Release();
    138.  
    139. return false;
    140. }
    141.  
    142. // Order the columns in the ContentsTable to conform to the
    143. // ones we want - which are mainly DisplayName, EntryID and
    144. // ObjectType
    145. // The table is guaranteed to set the columns in the order
    146. // requested
    147. //
    148. hr =lpAB->SetColumns( (LPSPropTagArray)&ptaEid, 0 );
    149.  
    150. if(HR_FAILED(hr)){
    151. if ( lpContainer )
    152. lpContainer->Release();
    153.  
    154. if ( lpAB )
    155. lpAB->Release();
    156.  
    157. return false;
    158. }
    159.  
    160. // Reset to the beginning of the table
    161. //
    162. hr = lpAB->SeekRow( BOOKMARK_BEGINNING, 0, NULL );
    163.  
    164. if(HR_FAILED(hr)){
    165. if ( lpContainer )
    166. lpContainer->Release();
    167.  
    168. if ( lpAB )
    169. lpAB->Release();
    170.  
    171. return false;
    172. }
    173.  
    174. // Read all the rows of the table one by one
    175. //
    176. int i = 1;
    177. do {
    178. hr = lpAB->QueryRows(1, 0, &lpRowAB);
    179.  
    180. if(HR_FAILED(hr)){
    181. break;
    182. }
    183.  
    184. if(lpRowAB) {
    185. cNumRows = lpRowAB->cRows;
    186.  
    187. if (cNumRows) {
    188. LPSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA;
    189. LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb;
    190. ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb;
    191.  
    192. // There are 2 kinds of objects - the MAPI_MAILUSER contact object
    193. // and the MAPI_DISTLIST contact object
    194. // We will only consider MAILUSER objects
    195. //
    196. if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) {
    197. // We will now take the entry-id of each object and cache it
    198. // on the listview item representing that object. This enables
    199. // us to uniquely identify the object later if we need to
    200. //
    201. LPSBinary lpSB = NULL;
    202.  
    203. m_lpWABObject->AllocateBuffer(sizeof(SBinary), (LPVOID *) &lpSB);
    204.  
    205. if(lpSB) {
    206. m_lpWABObject->AllocateMore(cbEID, lpSB, (LPVOID *) &(lpSB->lpb));
    207.  
    208. if(!lpSB->lpb) {
    209. m_lpWABObject->FreeBuffer(lpSB);
    210. continue;
    211. }
    212.  
    213. CopyMemory(lpSB->lpb, lpEID, cbEID);
    214. lpSB->cb = cbEID;
    215.  
    216.  
    217. contactsList.push_back(lpsz);
    218. contactsMap.insert(make_pair(i,lpSB));
    219. //LV_ITEM lvi = {0};
    220. //lvi.mask = LVIF_TEXT | LVIF_PARAM;
    221. //lvi.iItem = pListView->GetItemCount();
    222. //lvi.iSubItem = 0;
    223. //lvi.pszText = lpsz;
    224. //lvi.lParam = (LPARAM) lpSB;
    225.  
    226. // Now add this item to the list view
    227. //pListView->InsertItem(&lvi);
    228. }
    229. }
    230. }
    231. FreeProws(lpRowAB );
    232. }
    233. ++i;
    234. }while ( SUCCEEDED(hr) && cNumRows && lpRowAB) ;
    235.  
    236. return true;
    237. }
    238.  
    239. void CWAB::FreeProws(LPSRowSet prows)
    240. {
    241. ULONG irow;
    242. if (!prows)
    243. return;
    244.  
    245. for (irow = 0; irow < prows->cRows; ++irow)
    246. m_lpWABObject->FreeBuffer(prows->aRow[irow].lpProps);
    247.  
    248. m_lpWABObject->FreeBuffer(prows);
    249. }
    250.  
    251. void CWAB::ClearWABLVContents()
    252. {
    253. map<int,void *>::iterator mapIterator;
    254. for(mapIterator = contactsMap.begin(); mapIterator != contactsMap.end(); ++ mapIterator){
    255. if((*mapIterator).second){
    256. LPSBinary lpSB = (LPSBinary) (*mapIterator).second;
    257. m_lpWABObject->FreeBuffer(lpSB);
    258. }
    259. }
    260. }
    To copy to clipboard, switch view to plain text mode 

    Thanks a lot

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Quote Originally Posted by munna View Post
    CWAB::~CWAB()
    {
    if(m_SB.lpb)
    LocalFree(m_SB.lpb);

    if(m_bInitialized)
    {
    if(m_lpPropArray)
    m_lpWABObject->FreeBuffer(m_lpPropArray);

    if(m_lpAdrBook)
    m_lpAdrBook->Release();

    if(m_lpWABObject)
    m_lpWABObject->Release();

    if(m_hinstWAB)
    FreeLibrary(m_hinstWAB);
    }
    }
    Well... comment out everything except the first statement and see if it crashes. If not, uncomment next one and so on...

    Do you create copies of CWAB instances? To be sure add:
    Qt Code:
    1. private:
    2. CWAB( const CWAB& );
    3. CWAB& operator=( const CWAB& );
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Jan 2006
    Posts
    667
    Thanks
    10
    Thanked 80 Times in 74 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    This is the culprit

    Qt Code:
    1. if(m_hinstWAB)
    2. FreeLibrary(m_hinstWAB);
    To copy to clipboard, switch view to plain text mode 

    I load the library in the following way and therefore I need to free it.

    Qt Code:
    1. //This is the variable -->//HINSTANCE m_hinstWAB;
    2. m_hinstWAB = LoadLibrary( (lstrlen(szWABDllPath)) ? szWABDllPath : WAB_DLL_NAME );
    To copy to clipboard, switch view to plain text mode 

    Any ideas on how I can solve this?

    Thanks a lot !

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    What about those copies? Do you create only one object of CWAB class?

    Quote Originally Posted by munna View Post
    This is the culprit
    if(m_hinstWAB)
    FreeLibrary(m_hinstWAB);
    It's more a workaround, than a solution, but maybe you should load it before you create QApplication and free it after QApplication::exec() returns? Or maybe you should try to load it using QLibrary?

  7. #7
    Join Date
    Jan 2006
    Posts
    667
    Thanks
    10
    Thanked 80 Times in 74 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Quote Originally Posted by jacek View Post
    What about those copies? Do you create only one object of CWAB class?
    Yes I create only one object and its deleted once the window is closed.

    Quote Originally Posted by jacek View Post
    maybe you should load it before you create QApplication and free it after QApplication::exec() returns?
    But I don't need it through out the application. Only when user needs to access the Windows Address Book, I need to load the library. And once user is done, I free it.

    Quote Originally Posted by jacek View Post
    Or maybe you should try to load it using QLibrary?
    ok, will try that. But what will happen if I do not call FreeLibrary(m_hinstWAB); ?

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Quote Originally Posted by munna View Post
    But what will happen if I do not call FreeLibrary(m_hinstWAB); ?
    Nothing, if everything is implemented well. In worst case windows will think that this library is used by a non-existent process. Of course if you will create more than one CWAB object, you'll get a resource leak.

    Maybe you should try to reproduce that problem using a sample application? That crash might have more than one cause.

  9. #9
    Join Date
    Jan 2006
    Posts
    667
    Thanks
    10
    Thanked 80 Times in 74 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Quote Originally Posted by jacek
    Maybe you should try to reproduce that problem using a sample application?
    hmm, I am not sure what do you mean by that. I have a windows only code which accesses the windows address book and it works perfectly. I integrated that code with Qt code and it crashes the application

    Quote Originally Posted by jacek
    That crash might have more than one cause.
    When I comment those two lines, the app works perfectly (no crashes). But when I uncomment those lines, it crashes in the same place.

    May be I am missing something.

    Thanks a lot!

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: windows code troubling Qt

    Quote Originally Posted by munna View Post
    hmm, I am not sure what do you mean by that. I have a windows only code which accesses the windows address book and it works perfectly. I integrated that code with Qt code and it crashes the application
    So far we know that Qt + FreeLibrary() == crash. The question is: which part of Qt clashes with FreeLibrary().

Similar Threads

  1. C code linux to windows
    By deekayt in forum General Discussion
    Replies: 1
    Last Post: 19th October 2006, 22:17
  2. Problem closing a QMainWindow in Qt4.2
    By ian in forum Qt Programming
    Replies: 11
    Last Post: 17th October 2006, 00:49
  3. Replies: 5
    Last Post: 15th March 2006, 07:33
  4. Mac Port of Windows code
    By Nemo in forum Qt Programming
    Replies: 2
    Last Post: 13th February 2006, 07:37

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.