Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Re: SHBrowseForFolder works only one time when connecting to SQL server in between when using a manifest file

Re: SHBrowseForFolder works only one time when connecting to SQL server in between when using a manifest file

Scheduled Pinned Locked Moved C / C++ / MFC
databasesql-serversysadminhelpworkspace
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jens Doose
    wrote on last edited by
    #1

    Hi all, I experienced a strange behaviour, maybe one of you knows something about it. I have a little application that call SHBrowseForFolder, after that it connects to an SQL server via SQLDriverConnect. After some work it releases every allocated ODBC handle. Any subsequent call to SHBrowseForFolder will display an empty dialog, not even the controls are drawn. This happens only if there is a manifest file for this application to use the new common controls. I included the source code as a sample a little bit more down, if you would like the complete Devstudio workspace, just email me. I would be happy if any of you knows something about this, thanks in advance, Jens Source code: ----------------- #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #define BIF_USENEWUI (BIF_NEWDIALOGSTYLE | BIF_EDITBOX) #endif void Go() { // *** Doesn't help... // ::CoInitialize( 0 ); BROWSEINFO bi; ZeroMemory( &bi, sizeof( bi ) ); bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS; SHBrowseForFolder( &bi ); SQLHENV env = NULL; SQLRETURN sqlRet = SQLAllocEnv( &env ); SQLHDBC conn = NULL; sqlRet = SQLAllocConnect( env, &conn ); SQLCHAR szOut[ 2048 ] = {0}; SQLCHAR sqlConn[ 1024 ] = "DRIVER={SQL Server};SERVER=(local)"; // SQLCHAR sqlConn[ 1024 ] = "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=test\\"; SWORD len = 0; sqlRet = SQLDriverConnect( conn, NULL, sqlConn, SQL_NTS, szOut, sizeof( szOut ), &len, SQL_DRIVER_COMPLETE_REQUIRED ); if ( ( SQL_SUCCESS != sqlRet ) && ( SQL_SUCCESS_WITH_INFO != sqlRet ) ) { SWORD nMessageLen = 0; UCHAR szMessage[ SQL_MAX_MESSAGE_LENGTH ] = {0}; SDWORD dwNativeErrorCode = 0; UCHAR szErrorState[ SQL_SQLSTATE_SIZE + 1 ] = {0}; sqlRet = SQLError( env, conn, SQL_NULL_HSTMT, szErrorState, &dwNativeErrorCode, szMessage, SQL_MAX_MESSAGE_LENGTH - 1, &nMessageLen ); ::MessageBox( NULL, (CHAR*)szMessage, (CHAR*)szErrorState, MB_OK ); } sqlRet = SQLDisconnect( conn ); sqlRet

    D 1 Reply Last reply
    0
    • J Jens Doose

      Hi all, I experienced a strange behaviour, maybe one of you knows something about it. I have a little application that call SHBrowseForFolder, after that it connects to an SQL server via SQLDriverConnect. After some work it releases every allocated ODBC handle. Any subsequent call to SHBrowseForFolder will display an empty dialog, not even the controls are drawn. This happens only if there is a manifest file for this application to use the new common controls. I included the source code as a sample a little bit more down, if you would like the complete Devstudio workspace, just email me. I would be happy if any of you knows something about this, thanks in advance, Jens Source code: ----------------- #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #define BIF_USENEWUI (BIF_NEWDIALOGSTYLE | BIF_EDITBOX) #endif void Go() { // *** Doesn't help... // ::CoInitialize( 0 ); BROWSEINFO bi; ZeroMemory( &bi, sizeof( bi ) ); bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS; SHBrowseForFolder( &bi ); SQLHENV env = NULL; SQLRETURN sqlRet = SQLAllocEnv( &env ); SQLHDBC conn = NULL; sqlRet = SQLAllocConnect( env, &conn ); SQLCHAR szOut[ 2048 ] = {0}; SQLCHAR sqlConn[ 1024 ] = "DRIVER={SQL Server};SERVER=(local)"; // SQLCHAR sqlConn[ 1024 ] = "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=test\\"; SWORD len = 0; sqlRet = SQLDriverConnect( conn, NULL, sqlConn, SQL_NTS, szOut, sizeof( szOut ), &len, SQL_DRIVER_COMPLETE_REQUIRED ); if ( ( SQL_SUCCESS != sqlRet ) && ( SQL_SUCCESS_WITH_INFO != sqlRet ) ) { SWORD nMessageLen = 0; UCHAR szMessage[ SQL_MAX_MESSAGE_LENGTH ] = {0}; SDWORD dwNativeErrorCode = 0; UCHAR szErrorState[ SQL_SQLSTATE_SIZE + 1 ] = {0}; sqlRet = SQLError( env, conn, SQL_NULL_HSTMT, szErrorState, &dwNativeErrorCode, szMessage, SQL_MAX_MESSAGE_LENGTH - 1, &nMessageLen ); ::MessageBox( NULL, (CHAR*)szMessage, (CHAR*)szErrorState, MB_OK ); } sqlRet = SQLDisconnect( conn ); sqlRet

      D Offline
      D Offline
      David Crow
      wrote on last edited by
      #2

      After the first call to SHBrowseForFolder(), the 'bi' variable is not used again until the end of Go(). Is this intentional? What happens if you remove everything SQL/ODBC related? Does SHBrowseForFolder() work repeatedly then?

      J 1 Reply Last reply
      0
      • D David Crow

        After the first call to SHBrowseForFolder(), the 'bi' variable is not used again until the end of Go(). Is this intentional? What happens if you remove everything SQL/ODBC related? Does SHBrowseForFolder() work repeatedly then?

        J Offline
        J Offline
        Jens Doose
        wrote on last edited by
        #3

        bi is used again in the second call to SHBrowseForFolder. You could use another instance, that doesn't matter. SHBrowseForFolder works repeatedly is I remove the call to "sqlRet = SQLFreeHandle( SQL_HANDLE_ENV, env );" This happens only with the MS SQL Server ODBC driver. If another driver is used (MS Text driver, Sybase Anywhere) it works fine. Thanks, Jens

        D 1 Reply Last reply
        0
        • J Jens Doose

          bi is used again in the second call to SHBrowseForFolder. You could use another instance, that doesn't matter. SHBrowseForFolder works repeatedly is I remove the call to "sqlRet = SQLFreeHandle( SQL_HANDLE_ENV, env );" This happens only with the MS SQL Server ODBC driver. If another driver is used (MS Text driver, Sybase Anywhere) it works fine. Thanks, Jens

          D Offline
          D Offline
          David Crow
          wrote on last edited by
          #4

          Jens Doose wrote: bi is used again in the second call to SHBrowseForFolder. Right, but's it's still not being used. ;) The code pieces are disparate. The usage of 'bi' and the success/failure of the calls to SHBrowseForFolder() have nothing to do with the SQL-related stuff. It's considered good practice to check the return values from all function calls. Something like:

          void Go( void )
          {
          BROWSEINFO bi = {0};
          SQLRETURN sqlRet
          SQLHENV env = NULL;
          SQLHDBC conn = NULL;
          SWORD len = 0,
          nMessageLen = 0;
          SQLCHAR szOut[2048] = {0},
          sqlConn[1024] = "DRIVER={SQL Server};SERVER=(local)";
          UCHAR szMessage[ SQL_MAX_MESSAGE_LENGTH ] = {0},
          szErrorState[ SQL_SQLSTATE_SIZE + 1 ] = {0};
          SDWORD dwNativeErrorCode = 0;

          bi.ulFlags = BIF\_NEWDIALOGSTYLE | BIF\_RETURNONLYFSDIRS;
          
          SHBrowseForFolder( &bi );
          
          sqlRet = SQLAllocEnv(&env);
          if (SQL\_SUCCESS == sqlRet)
          {
              sqlRet = SQLAllocConnect(env, &conn);
              if (SQL\_SUCCESS == sqlRet)
              {
                  sqlRet = SQLDriverConnect(conn, NULL, sqlConn, SQL\_NTS, szOut, sizeof(szOut), &len, SQL\_DRIVER\_COMPLETE\_REQUIRED);
                  if (SQL\_SUCCESS != sqlRet && SQL\_SUCCESS\_WITH\_INFO != sqlRet)
                  {
                      sqlRet = SQLError(env, conn, SQL\_NULL\_HSTMT, szErrorState, &dwNativeErrorCode, szMessage, SQL\_MAX\_MESSAGE\_LENGTH - 1, &nMessageLen);
          
                      ::MessageBox(NULL, (CHAR \*) szMessage, (CHAR \*) szErrorState, MB\_OK);
                  }
          
                  sqlRet = SQLDisconnect(conn);
          
                  sqlRet = SQLFreeHandle(SQL\_HANDLE\_DBC, conn);
              }
          
              sqlRet = SQLFreeHandle( SQL\_HANDLE\_ENV, env );
          }
          
          ZeroMemory(&bi, sizeof(bi));
          bi.ulFlags = BIF\_NEWDIALOGSTYLE | BIF\_RETURNONLYFSDIRS;
          SHBrowseForFolder(&bi);
          

          }

          Jens Doose wrote: This happens only with the MS SQL Server ODBC driver. If another driver is used (MS Text driver, Sybase Anywhere) it works fine. Or it's just being masked such that it appears fine.

          J 1 Reply Last reply
          0
          • D David Crow

            Jens Doose wrote: bi is used again in the second call to SHBrowseForFolder. Right, but's it's still not being used. ;) The code pieces are disparate. The usage of 'bi' and the success/failure of the calls to SHBrowseForFolder() have nothing to do with the SQL-related stuff. It's considered good practice to check the return values from all function calls. Something like:

            void Go( void )
            {
            BROWSEINFO bi = {0};
            SQLRETURN sqlRet
            SQLHENV env = NULL;
            SQLHDBC conn = NULL;
            SWORD len = 0,
            nMessageLen = 0;
            SQLCHAR szOut[2048] = {0},
            sqlConn[1024] = "DRIVER={SQL Server};SERVER=(local)";
            UCHAR szMessage[ SQL_MAX_MESSAGE_LENGTH ] = {0},
            szErrorState[ SQL_SQLSTATE_SIZE + 1 ] = {0};
            SDWORD dwNativeErrorCode = 0;

            bi.ulFlags = BIF\_NEWDIALOGSTYLE | BIF\_RETURNONLYFSDIRS;
            
            SHBrowseForFolder( &bi );
            
            sqlRet = SQLAllocEnv(&env);
            if (SQL\_SUCCESS == sqlRet)
            {
                sqlRet = SQLAllocConnect(env, &conn);
                if (SQL\_SUCCESS == sqlRet)
                {
                    sqlRet = SQLDriverConnect(conn, NULL, sqlConn, SQL\_NTS, szOut, sizeof(szOut), &len, SQL\_DRIVER\_COMPLETE\_REQUIRED);
                    if (SQL\_SUCCESS != sqlRet && SQL\_SUCCESS\_WITH\_INFO != sqlRet)
                    {
                        sqlRet = SQLError(env, conn, SQL\_NULL\_HSTMT, szErrorState, &dwNativeErrorCode, szMessage, SQL\_MAX\_MESSAGE\_LENGTH - 1, &nMessageLen);
            
                        ::MessageBox(NULL, (CHAR \*) szMessage, (CHAR \*) szErrorState, MB\_OK);
                    }
            
                    sqlRet = SQLDisconnect(conn);
            
                    sqlRet = SQLFreeHandle(SQL\_HANDLE\_DBC, conn);
                }
            
                sqlRet = SQLFreeHandle( SQL\_HANDLE\_ENV, env );
            }
            
            ZeroMemory(&bi, sizeof(bi));
            bi.ulFlags = BIF\_NEWDIALOGSTYLE | BIF\_RETURNONLYFSDIRS;
            SHBrowseForFolder(&bi);
            

            }

            Jens Doose wrote: This happens only with the MS SQL Server ODBC driver. If another driver is used (MS Text driver, Sybase Anywhere) it works fine. Or it's just being masked such that it appears fine.

            J Offline
            J Offline
            Jens Doose
            wrote on last edited by
            #5

            Hi David, that is true. But that was not my point, maybe I didn't make myself clear enough. The problem is that with Windows XP the second call to SHBrowseForFolder does not work, either it isn't shown at all (when there is no manifest file) or the dialog is shown, but it doesn't contain the control, which displays all the folders (when having a manifest file). And this problem only occurs when making a SQLDriverConnect to an MS SQL ODBC driver in between this two calls. Any other driver is fine. I discovered the problem in a much more complex environment, and believe me, it did cost me some hours of my life to hunt the problem down to this constellation ;-). To clarify the problem I wrote a simple test app that just calls SHBrowseForFolder and SQLDriverConnect. That is why there is no error checking or why I don't use the result value within bi. Thanks Jens

            D 1 Reply Last reply
            0
            • J Jens Doose

              Hi David, that is true. But that was not my point, maybe I didn't make myself clear enough. The problem is that with Windows XP the second call to SHBrowseForFolder does not work, either it isn't shown at all (when there is no manifest file) or the dialog is shown, but it doesn't contain the control, which displays all the folders (when having a manifest file). And this problem only occurs when making a SQLDriverConnect to an MS SQL ODBC driver in between this two calls. Any other driver is fine. I discovered the problem in a much more complex environment, and believe me, it did cost me some hours of my life to hunt the problem down to this constellation ;-). To clarify the problem I wrote a simple test app that just calls SHBrowseForFolder and SQLDriverConnect. That is why there is no error checking or why I don't use the result value within bi. Thanks Jens

              D Offline
              D Offline
              David Crow
              wrote on last edited by
              #6

              Jens Doose wrote: The problem is that with Windows XP Have you tried this on another platform to see if it is OS related? Jens Doose wrote: That is why there is no error checking or why I don't use the result value within bi. That's fine, and is common practice. I just wanted to emphasize that omitting error checking might have been the crux of the problem. If you commented out both calls to SHBrowseForFolder(), thus leaving only the SQL-related code, can Go() be called repeatedly? Perhaps after you are done with SHBrowseForFolder(), you should call IMalloc::Free().

              HRESULT hr;
              LPMALLOC pMalloc;
              LPITEMIDLIST pidlSelected = NULL;
              hr = SHGetMalloc(&pMalloc);
              pidlSelected = SHBrowseForFolder(&bi);
              ...
              pMalloc->Free(pidlSelected);

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups