Link to home
Start Free TrialLog in
Avatar of Hanqian
Hanqian

asked on

How to get default printer?

I use this function:
GetDefaultPrinter(..,..) to get the printer name, I have
include the header files:
#include "winspool.h"
#include "windows.h"

I also upgradte latest SDK, but still GetDefaultPrinter is  undefined, My computer is windowXP.

Thanks.
Hanqian
Avatar of wayside
wayside

Did you add winspool.lib to the list of libraries to link in?

Project Properties->Linker->Input, add it to the end of the "Additional dependencies" line (for VC++.Net).
Avatar of Hanqian

ASKER

I added it , but it still doesn't recognize GetDefaultPrinter(..,..).

Thanks.
Hanqian
Made sure that your DevStudio is looking at correct version of header files and library. Check how many copies of them you have on your machine.
Can you give us the *exact* error message, making sure it has the error number? And tell us which version of VisualStudio you are using?

I just created a new SDI project from scratch, added a call to GetDefaultPrinter(), and built it. It worked perfectly without me having to specify any extra libraries. Examination of the exe shows that it pulls it out of winspool.drv . This is on VC++.Net 2003.
Avatar of Hanqian

ASKER

Error:
error C2065: 'GetDefaultPrinter' : undeclared identifier

version of VisualStudio:
MSDEV98.

Thanks.
Hanqian
Open up winspool.h and search for GetPrinterDefault. It's not a supported function on windows 98, so your development environment may not know about it even though you are running XP. An up-to-date SDK probably has it, in which case you need to make sure that the SDK include directories are being checked before the VisualStudios directories.

i agree with wayside, it want working on mine too, until i got the latest sdk from
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
You can use the function in the following url:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;246772
This is because this function is Included in Windows 2000 and later so if your application's target OS is not specified explicitly win2k it wan't compile and it gives error because in spool.h definition of this function is conditionally included. better way is to check the os and accordingly call the function. please tell me your application's target os and I will provide you code.
in 9x and NT you have to do little trick( I know it and I did it in my application)


vijay
Avatar of Hanqian

ASKER

Hi Wayside,

I have found that in latest installed SDK in my Program File directory, Winspool.h has
GetDefaultPrinter, but not in WinSpool.h  which is in Program File/Microsoft Visual Studio/ directory
, how to make sure that the SDK include directories are being checked before the VisualStudios directories??
Why SDK doesn't overwrite the same files in Visual Studio??

Thanks.

Hi Vijay,
I am not quite sure what application's target os means, my application works for Window 2000
, Window NT and WIndowXp.

Thanks.
     if(m_nOsVer == NT4)
      {
            if(!szDefPrnName)
            {
                  WriteLog("Printer name not specified for %s",szPrnName);
                  return FALSE;
            }
            HKEY  hKey=NULL;
            TCHAR valbuff[MAX_PATH];
            ZeroMemory(valbuff,MAX_PATH);
            DWORD dwType = REG_SZ;
            DWORD cbBuff  = MAX_PATH;
            char* buff = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices");
      
            long result = RegOpenKeyEx(HKEY_CURRENT_USER,buff,NULL,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey);
            if(ERROR_SUCCESS != result )
            {
                  WriteLog("GetDefaultPrn: Error accessing Registery ");
                  return FALSE;
            }
            bRet = RegQueryValueEx(hKey,szDefPrnName,NULL,&dwType,(BYTE*)valbuff,&cbBuff);
            if(ERROR_SUCCESS != bRet)
            {
                  WriteLog("GetDefaultPrn: Error accessing Registery ");
                  return FALSE;
            }
            if(!valbuff || _tcslen(valbuff) <= 0)
            {
                  m_bNoDefPrn = TRUE;
                  return FALSE;
            }
            _tcscat(szDefPrnName,",");
            _tcscat(szDefPrnName,valbuff);
            RegCloseKey(hKey);
            buff = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
            result = RegOpenKeyEx(HKEY_CURRENT_USER,buff,NULL,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey);
            if(ERROR_SUCCESS != result )
            {
                  WriteLog("GetDefaultPrn: Error accessing Registery ");
                  return FALSE;
            }
            bRet= RegSetValueEx(hKey,_T("Device"),NULL,dwType,(const BYTE*)szDefPrnName,_tcslen(szDefPrnName));
            bRet= (bRet==ERROR_SUCCESS);
            RegCloseKey(hKey);
      

      }
      else if(m_nOsVer >= WIN2K)
      {
            typedef BOOL ( WINAPI *SETDEFPRN)(LPCSTR );
            //Old version of winspool.drv may not have this function so
            //better check it out.
            HINSTANCE hSpoolib = LoadLibrary(_T("winspool.drv"));
            if(hSpoolib)
            {
                  SETDEFPRN SetDefPrn = (SETDEFPRN)GetProcAddress(hSpoolib,_T("SetDefaultPrinterA"));
                  if(SetDefPrn)
                  {
                        if(!SetDefPrn((LPCSTR)szPrnName))
                        {
                              WriteLog("Failed to set printer %s default",szPrnName);
                              bRet = FALSE;
                        }
                        //else// default printer is set
                        //      m_bDefPrnSet = TRUE;//so do not take care about default printer now onward
                  }
                  else
                  {
                        WriteLog("Function SetDefaultPrinter not found");
                        bRet = FALSE;
                  }
                  FreeLibrary(hSpoolib);

            }
            else
            {
                  WriteLog("Load library %s failed",_T("winspool.drv"));
                  bRet = FALSE;
            }
      }//IF >= WIN2K
Avatar of Hanqian

ASKER

Hi Vijay,

I tried just this part code:  else if(m_nOsVer >= WIN2K), it doesn't work, it returns
printer name with garbage.

Thanks.
Avatar of Hanqian

ASKER

Hi Vijay,

Since I am getting Default info. Should this line code :
 SETDEFPRN SetDefPrn = (SETDEFPRN)GetProcAddress(hSpoolib,_T("SetDefaultPrinterA"));
be:
 GETDefPrn = (GETDEFPRN)GetProcAddress(hSpoolib,_T("GetDefaultPrinterA")); ??

Hanqian

When you look at  http://support.microsoft.com/default.aspx?scid=kb;EN-US;246772

you will see two functions: DPGetDefaultPrinter() and DPSetDefaultPrinter()

These functions works for all versions of Windows and written by Microsoft, which will work fine (I didn't try yet, 'cos I don't have a chance to).

So those functions will do all *tricks* and stuff..

Caner
is printspooler service is running ?
because this code is working fine here
ASKER CERTIFIED SOLUTION
Avatar of wayside
wayside

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Hanqian

ASKER

Hi Caner,

I have tried it, it wouldn't complie for me, it complaints:

///////////////////////////////////
 fnGetDefaultPrinter = GetProcAddress(hWinSpool, GETDEFAULTPRINTER);
      if (!fnGetDefaultPrinter)
      {
        FreeLibrary(hWinSpool);
        return FALSE;
      }

      bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);
///////////////////////////////////////////////////////
fnGetDefaultPrinter(pPrinterName, pdwBufferSize):too many actual parameters

Thanks.

in your projec settings goto c++ and preprocessor catategory set
additional include directories with your path to sdk include like

e:\program files\Microsoft SDK\include

make sure that printspooer service is running and you have some printer set and make it default and just run following program

#include "stdio.h"
#include "windows.h"
#include "winspool.h"

int main(int argc, char* argv[])
{
    char szPrnName[250];
      DWORD dwSize = 250;
      if(!GetDefaultPrinter(szPrnName,&dwSize))
      {
            int d = GetLastError();
            if(d == ERROR_INSUFFICIENT_BUFFER)
                  printf("ERROR_INSUFFICIENT_BUFFER");
            else
                  if(d == ERROR_FILE_NOT_FOUND)
                        printf("ERROR_FILE_NOT_FOUND");
      }
      printf("Default printer %s \n",szPrnName);
      return 0;
}

Avatar of Hanqian

ASKER

Hi wayside,

Finialy I got it work, you said:

You should see directories for VC++, and then at the bottom a directory for the SDK. For example, mine shows
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE
C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE
C:\Program Files\Microsoft SDK\Include
Make sure the directory for the SDK is at the bottom.

But it didn't work until I put the directory for the SDK is at the top. Now i get the function
GetDefaultPrinter works now. Thank you so much.
My thanks  also goes all the people who have help me here.

Hanqian.