Solved

How to get default printer?

Posted on 2004-04-09
19
2,484 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:Hanqian
  • 7
  • 4
  • 4
  • +3
19 Comments
 
LVL 14

Expert Comment

by:wayside
ID: 10793729
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).
0
 

Author Comment

by:Hanqian
ID: 10794069
I added it , but it still doesn't recognize GetDefaultPrinter(..,..).

Thanks.
Hanqian
0
 
LVL 8

Expert Comment

by:gelbert
ID: 10794249
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.
0
 
LVL 14

Expert Comment

by:wayside
ID: 10794485
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.
0
 

Author Comment

by:Hanqian
ID: 10794513
Error:
error C2065: 'GetDefaultPrinter' : undeclared identifier

version of VisualStudio:
MSDEV98.

Thanks.
Hanqian
0
 
LVL 14

Expert Comment

by:wayside
ID: 10794609
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.

0
 
LVL 4

Expert Comment

by:bkfirebird
ID: 10795121
i agree with wayside, it want working on mine too, until i got the latest sdk from
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10795283
You can use the function in the following url:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;246772
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10803770
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
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:Hanqian
ID: 10805836
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.
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10805980
     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
0
 

Author Comment

by:Hanqian
ID: 10806130
Hi Vijay,

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

Thanks.
0
 

Author Comment

by:Hanqian
ID: 10806268
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

0
 
LVL 4

Expert Comment

by:caner_elci
ID: 10806307
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
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10806388
is printspooler service is running ?
because this code is working fine here
0
 
LVL 14

Accepted Solution

by:
wayside earned 100 total points
ID: 10806550
>, how to make sure that the SDK include directories are being checked before the
>VisualStudios directories??

Open up the "Tools" pulldown menu and select "Options".
 Click the tab that says "Directories", you should see a combo box labeled "Show directories for:", pull this down and select "Include files".

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.

If there is no entry for the SDK, you can add one. There should be a rectangle at the bottom of the list, if you double-click in it you can enter another directory or browsae for one.

The same is true for the Library files pulldown from the combo box. Mine shows

C:\Program Files\Microsoft SDK\Lib

for the SDK.

Also for "Executable files", mine has at the bottom

C:\Program Files\Microsoft SDK\Bin
C:\Program Files\Microsoft SDK\Bin\WinNT


> Why SDK doesn't overwrite the same files in Visual Studio??

That's just not how the installer does it. It creates its own directories for the SDK, and then can modify the VS environment to look there first.

0
 

Author Comment

by:Hanqian
ID: 10806606
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.

0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10806964
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;
}

0
 

Author Comment

by:Hanqian
ID: 10807214
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.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now