473,397 Members | 1,961 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

How to get printer name properly using PRINTDLG struct and PrintDlg Function?

1,059 1GB
I am having a silly trouble.

I am not getting printer name properly using
PRINTDLG struct and PrintDlg Function.

I tried to follow the suggestion provided in msdn it is not working. The test code is added below,

Expand|Select|Wrap|Line Numbers
  1. #include <windows.h>
  2. #include <stdio.h>
  3.  
  4. int main()
  5. {
  6.     PRINTDLG pd;
  7.     DEVNAMES *pDevNames;
  8.     DEVMODE *pDevMode;
  9.  
  10. // Initialize PRINTDLG
  11.     ZeroMemory(&pd, sizeof(pd));
  12.  
  13.     wchar_t *wt;
  14.     char *c;
  15.  
  16.     pd.lStructSize = sizeof(pd);
  17.     pd.hwndOwner   = NULL;
  18.     pd.hDevMode    = NULL;     // Don't forget to free or store hDevMode.
  19.     pd.hDevNames   = NULL;     // Don't forget to free or store hDevNames.
  20.     pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; 
  21.     pd.nCopies     = 1;
  22.     pd.nFromPage   = 0xFFFF; 
  23.     pd.nToPage     = 0xFFFF; 
  24.     pd.nMinPage    = 1; 
  25.     pd.nMaxPage    = 0xFFFF; 
  26.  
  27.     if (PrintDlg(&pd)==TRUE) 
  28.     {
  29.         // GDI calls to render output. 
  30.         pDevMode = (DEVMODE* )pd.hDevMode;
  31.         pDevNames = (DEVNAMES*)pd.hDevNames;
  32.         LPCTSTR     szDriver;
  33.         LPCTSTR     szDevice;
  34.         LPCTSTR     szOutput;
  35.         szDriver = (LPCTSTR)pDevNames+pDevNames->wDriverOffset;
  36.         szDevice = (LPCTSTR)pDevNames+pDevNames->wDeviceOffset;
  37.         szOutput = (LPCTSTR)pDevNames+pDevNames->wOutputOffset;
  38.  
  39.               wprintf(L"%s",szDevice);      
  40.     }
  41.  
  42.  
  43.  
  44. }
  45.  
If you ask why do you need printer name

The reason is when user would run the program first time it wont have any printer name. So it would return null handler. after getting null handler printer dialog will open automatically. From here user will Select the printer. At this stage I want to store the printer name for next time. Next time software wont ask for printer name again unless it is getting null handler

Best Regards,
Johny
Dec 18 '10 #1
9 7292
johny10151981
1,059 1GB
Didnt find the solution. But have created an alternative solution.

using EnumPrinters function I have find out all the name of the printer and then populate a combobox. That is how i have solved the issue temporarily.

But Yet It would do great If I can have the solution to get the selected printer name
Dec 20 '10 #2
weaknessforcats
9,208 Expert Mod 8TB
You might be getting in trouble with TCHAR. That is, you can't use wchar_t* and LPCTSTR in the same code.

I suggest you code completely in TCHAR so that your wchar_t* becomes LPTSTR.

Then set the project to be either ASCII or Unicode.

Also be sure to use the correct TCHAR mapped functions.
Dec 20 '10 #3
johny10151981
1,059 1GB
Weaknessforcat,
I dont get it. Why you said so?
TCHAR is
Expand|Select|Wrap|Line Numbers
  1. typedef WCHAR TCHAR
  2. typedef wchar_t WCHAR
  3.  
so there is no difference between wchar_t and TCHAR

and LPCSTR
Expand|Select|Wrap|Line Numbers
  1. typedef const char *LPCSTR;
  2.  
wchar_t/TCHAR and (const char*)/LPCSTR is completely different variable.

By default a Visual studio 2005 project setup is UNICODE. Which mean whenever you will call a Windows function it will call the Unicode version of that individual Function (depending on availability).

As Example :
Expand|Select|Wrap|Line Numbers
  1. #ifdef UNICODE
  2. #define CreateWindowEx  CreateWindowExW
  3. #else
  4. #define CreateWindowEx  CreateWindowExA
  5. #endif // !UNICODE
  6.  
Above code is from WinUser.h
so according to above code when this project is defined as UNICODE, When you would call

CreateWindowEx you will get CreateWindowExW

otherwise CreateWindowExA.

Now the difference between the two version of the function

Expand|Select|Wrap|Line Numbers
  1. WINUSERAPI
  2. HWND
  3. WINAPI
  4. CreateWindowExA(
  5.     __in DWORD dwExStyle,
  6.     __in_opt LPCSTR lpClassName,
  7.     __in_opt LPCSTR lpWindowName,
  8.     __in DWORD dwStyle,
  9.     __in int X,
  10.     __in int Y,
  11.     __in int nWidth,
  12.     __in int nHeight,
  13.     __in_opt HWND hWndParent,
  14.     __in_opt HMENU hMenu,
  15.     __in_opt HINSTANCE hInstance,
  16.     __in_opt LPVOID lpParam);
  17. WINUSERAPI
  18. HWND
  19. WINAPI
  20. CreateWindowExW(
  21.     __in DWORD dwExStyle,
  22.     __in_opt LPCWSTR lpClassName,
  23.     __in_opt LPCWSTR lpWindowName,
  24.     __in DWORD dwStyle,
  25.     __in int X,
  26.     __in int Y,
  27.     __in int nWidth,
  28.     __in int nHeight,
  29.     __in_opt HWND hWndParent,
  30.     __in_opt HMENU hMenu,
  31.     __in_opt HINSTANCE hInstance,
  32.     __in_opt LPVOID lpParam);
  33.  
in Widestring version lpClassName is Wide string

i.e LPCWSTR which is typedef const wchar_t *LPCWSTR

If you call to call ANSII version specifically you will to call
CreateWindowsExA

But If you look at the functions related with STRING
There is no Modification using macro

example:
Expand|Select|Wrap|Line Numbers
  1. #include <windows.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. int main()
  6. {
  7.     TCHAR wpart1[20]=L"My Name ";
  8.     wchar_t wpart2[]=L"Johny.";
  9.  
  10.     CHAR cpart1[20]="What is your ";
  11.     char cpart2[]="Name?";
  12.  
  13.     wcscat(wpart1,wpart2);
  14.     strcat(cpart1,cpart2);
  15.  
  16.     wprintf(L"%s\n",wpart1);
  17.     printf("%s\n",cpart1);
  18. }
  19.  
Above code will give a clear Idea about char, wchar_t and their type modifier(confused about what to call it).
Dec 20 '10 #4
weaknessforcats
9,208 Expert Mod 8TB
there is no difference between wchar_t and TCHAR
a TCHAR is a char when the project is ASCII and is a wchar_t when the project is Unicode.

You do not want any TCHAR in your code unless all the code is TCHAR.

TCHAR is to seamlessly let you compile ASCII and Unicode versions of your program. If you are only using Unicode, then att TCHAR must be wcar_t.


L"My Name ";
This does not make a Unicde string. This makes a string of wchar_t whicg may or may not be Unicode based on the encoding technique. You have to call a function to create the Unicode string. Like SysAllocStrng or MultibyteToWideChar.

All wchar_t should be WCHAR in the code. That is, there should be no native types in the program.

Your original post used LPCTSTR, which is a long pointer to a constant TCHAR string. If your code is Unicode only then you use LPCWSTR.

If you don't follow exactly, you get weird results. Like L"Hello" is not a LPWSTR.
Dec 21 '10 #5
johny10151981
1,059 1GB
same program with (XmultibyteX) wide character
Expand|Select|Wrap|Line Numbers
  1. #include <windows.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. int main()
  6. {
  7.     TCHAR wpart1[20]=L"私の名前はジョン ";
  8.     wchar_t wpart2[]=L"ジョン.";
  9.  
  10.     CHAR cpart1[20]="私の名前はジョン ";
  11.     char cpart2[]="ジョン?";
  12.  
  13.     wcscat(wpart1,wpart2);
  14.     strcat(cpart1,cpart2);
  15.  
  16.     wprintf(L"%s\n",wpart1);
  17.     printf("%s\n",cpart1);
  18.  
  19. }
  20.  
Dec 21 '10 #6
johny10151981
1,059 1GB
Dear WeaknessforCat,
Sorry for being rude in my last reply.
Let me explain some of issue you mentioned.

so far I stand for what I said.

The point you mentioned

L"My Name ";

adding L in front of string force compiler to read the string as wide string.

Now Lets come to version issue. (I recalled it in the train :D ). in University I worked with Visual Studio 6. In that version I saw that garbage value you talked about.
as example

Expand|Select|Wrap|Line Numbers
  1. CreateWindow("TEXTCLASS","TEXT TO DISPLAY", .........);
  2.  
if this code is compiled at visual studio 6 "TEXT TO DISPLAY" would create garbage data on the title bar. to ensure not to make garbage value I used to used
Expand|Select|Wrap|Line Numbers
  1. TEXT("What ever the data is"); //it force the compiler to read this particular text as wide string character
  2.  
But Just the garbage value was the issue but no compilation error at all. (I dont know who did that: the Definition of UNICODE or just new feature of Compiler). But in Version 8. IF you do not make sure of wide character you will get a compilation error.

If you take a look to above example i gave. You will get garbage data in the character field. But you Will get the proper data in wide character field.
Dec 22 '10 #7
In case, like me, anyone has to do the same thing, gets hung up at the same spot and comes googling here for an answer: the code works except that the memory block must be locked and unlocked. ie:

Expand|Select|Wrap|Line Numbers
  1.     DEVNAMES *pDevNames = (DEVNAMES*)GlobalLock(pd.hDevNames);
  2.     LPCTSTR szDriver;
  3.     LPCTSTR szDevice;
  4.     LPCTSTR szOutput;
  5.     szDriver = (LPCTSTR)pDevNames + pDevNames->wDriverOffset;
  6.     szDevice = (LPCTSTR)pDevNames + pDevNames->wDeviceOffset;
  7.     szOutput = (LPCTSTR)pDevNames + pDevNames->wOutputOffset;
  8.     GlobalUnlock(pd.hDevNames);
Aug 4 '11 #8
weaknessforcats
9,208 Expert Mod 8TB
Expand|Select|Wrap|Line Numbers
  1. L"My Name "; 
  2.  
  3. adding L in front of string force compiler to read the string as wide string.
Just so long as you understand that a wide string is not a UNICODE string.

That means L"My Name " cannot be used as a UNICODE WSTR. If you try you get weird results. Further if you compile this code in ASCII the string is not a char string. Therefore you must code this as:

TEXT("MyName") or as _T("MyName")

There is an entre section of MSDN about how to code in TCHAR. And remember, that if you don't need an ASCII version of your code then you code directly in WCHAR and create yout stirngs using the wide version of MultiByteToWideChar to get the UNICODE version of the literal.

Finally, if you need localiztion of your code, yu can't have hard-coded lierals in it. Instead you need localization code to generate a UNICODE version of the string in the correct language. Here again, MSDN is you best resource or use the book Windows via C/C++ by Jeffrey Richter.
Aug 4 '11 #9
johny10151981
1,059 1GB
Well thanks people for your response.

I guess _T is obsolete by now.

I have developed few applications already with wide character. and the problem i was facing was not related with Wide character or anything else. the problem was absolutely related with microsoft documentationa. because they have suggested one structure(now i cannot recall) but in fact it works with a different structure and i think i answered myself in other thread.
Aug 4 '11 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

0
by: Jim Warner | last post by:
I am having problems using Borland 5.02 C/C++ for testing printer status repeatly. I wish to use my printer to detect off-line, removing paper, and so on with my software. I have tried using...
2
by: charles hamm | last post by:
I'm trying to use PrintDlg (and PRINTDLG) to create a printer dialog with landscape as the default. Here is my code (from within a CDialog-based class): PRINTDLG printDlg; ZeroMemory(&printDlg,...
0
by: ripal.soni | last post by:
Hi there I am .net developer ,right now working on a project in that i need to print pdf file using vb.net and i also have to pass printer name as argument ,file should be printed on a...
0
by: Sudheer Gupta | last post by:
Hi, I am having trouble using C struct in python. Hope anyone can help me out ... Say, I have my C struct as typedef struct call { struct call *next;
3
by: Sudheer Gupta | last post by:
Hi, I am having trouble using C struct in python. Hope anyone can help me out ... Say, I have my C struct as typedef struct call { struct call *next;
2
by: drsudhak | last post by:
Hi every I Have to get Printer Name For Given Port Number/Name using VB6.0 Code
3
by: ripal.soni | last post by:
To Print file on your selected printer instead of default printer you can write the following code also you can find the complete solution in...
1
by: saurindoshi | last post by:
Hi guys, How can i get the printer name and IP address in local network which containing more than two printer? and also which document is printed by which user on which printer thru javascript ?
10
by: bhughes2187 | last post by:
Hey all, The access app I am creating, pulls a .dbf file into a table in access. The name of the printer to be printed to is contained in that file/table. How would I cycle through the list of...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.