|
Hi,
Just a quick question. I have a bitmap resource in my project and I load it by calling
LoadBitmap but how can I resize it on the fly so that it fits neatly into my window?
I need to do it before I display as I don't have control over the BitBlt display code in the MFC control.
Thanks.
|
|
|
|
|
You need to create a new bitmap that is the right size, then stretchblt your bitmap into it.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Do you have an example?
Thanks
|
|
|
|
|
If you look up stretchblt in the MSDN, I'm sure it will have an example.
Just make sure you set the correct mode ( COLORONCOLOR is the high quality one, from memory )
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
awesome
so I have done that and it works great.
With regard to releasing GDI resources I get a little confused about what I have to put back.
I have two device contexts in which I SelectObject the two bitmaps.
I re select the old bitmaps back. Is this all I have to do?
Do I need to call DeleteObject as well?
Thanks
|
|
|
|
|
Anonymous wrote:
so I have done that and it works great.
Terrific
Anonymous wrote:
I have two device contexts in which I SelectObject the two bitmaps.
I re select the old bitmaps back. Is this all I have to do?
If you're using MFC, the CDC and CBitmap classes will clean up after you once you've done the above. If you're using straight handles then you'll need to call DeleteObject yourself.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Christian Graus wrote:
If you're using MFC, the CDC and CBitmap classes will clean up after you once you've done the above. If you're using straight handles then you'll need to call DeleteObject yourself.
Not quite Christian, you do have to select the bitmaps out of the DC before you let the destructors clean up. The easiest way to call CDC::SaveDC before you select any objects in, and CDC::RestoreDC when you are finished with the DC.
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
|
PJ Arends wrote:
you do have to select the bitmaps out of the DC before you let the destructors clean up.
Um.. if you follow the conversation, what I meant by 'once you've done the above' is that the original poster indicated that he had selected the bitmaps out of the DC, and asked if he needed to call 'DeleteObject', having done that.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Ok, my bad. It is just that I have used code that leaked resources like crazy because people didn't restore the DC, they just let the destructor do it's thing. Then they would say it doesn't matter, because Win2K / XP has no limit on resource usage.
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
|
I wrote a small program to shutdown my computer at a scheduled time (using the task scheduler to run the program at the end of the day). The program works except when I'm logged off from the computer (i.e. the welcome or login screen is displayed). The program still runs and terminates will an exit code of 0, but the shutdown never happened. Here's a sample of the code:
void CPowerdownDlg::OnOK() <br />
{<br />
if (!mode)
{<br />
HANDLE procHnd, tokHnd;<br />
<br />
procHnd = GetCurrentProcess();<br />
<br />
if (!OpenProcessToken(procHnd,TOKEN_ADJUST_PRIVILEGES,&tokHnd))<br />
return;<br />
<br />
TOKEN_PRIVILEGES tp;<br />
LUID luid;<br />
<br />
if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid))<br />
return; <br />
<br />
tp.PrivilegeCount = 1;<br />
tp.Privileges[0].Luid = luid;<br />
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;<br />
<br />
AdjustTokenPrivileges(tokHnd, FALSE, &tp, 0, NULL, 0); <br />
<br />
InitiateSystemShutdownEx(NULL, NULL, 15, TRUE, FALSE, SHTDN_REASON_FLAG_PLANNED);<br />
<br />
}<br />
else if (mode == 1)
SetSuspendState(FALSE,TRUE,FALSE);<br />
else if (mode == 2)
SetSuspendState(TRUE,TRUE,FALSE);<br />
<br />
OnClose();<br />
}
This is an MFC app where the dialog displays a countdown to auto-shutdown or the user can force it manually (by clicking the OK button). Of course when no one is logged on, the program will shutdown the computer without user intervention. I've tried using ExitWindowsEx() but the results were the same. Strange though that hibernating (mode 2) works when I'm logged off. I'm using XP Pro.
I'm puzzled
reymano
|
|
|
|
|
Not really a VC++ question, but can someone point me to a link that describes how to do simple string parsing in a .cmd script. I'd like to parse an incoming arg like "1.2.3" into "1", "2" and "3".
Thanks!
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
Try here[^]. They've got a lot of information on batch file 'programming', in addition to an immense pile of registry hacks.
For the basics, you can read the help for the SET, IF, and FOR commands from the command line using this:
C:\> set /? | more
Software Zen: delete this;
|
|
|
|
|
Hi all,
As you know we have an interface in windows called ICOPYHOOK.
With this interface you can only monitor Copying of FOLDER(S) and PRINTER objects.
Could any one tell me how can i write an application to monitoring FILE Copying.?
Is there any resourec for this purpose on the web.please show me.
Thanks.
|
|
|
|
|
|
Hi, I'm currently developing a program which is supposed to run on Windows 98/NT4/ME/2000/XP/whatevercomesafterthis and I was wondering what messing with WINVER might have a result on the program. By that I mean, does the program still work if I set it to like 0x500 or something?
I suppose that if it works, the feature used for this version won't be available on Windows 98.
MSDN doesn't really enlighten me on this matter, but I was just wondering if this would break the program when running on Windows 98 or anything.
|
|
|
|
|
For 95 and greater the two defines you use are:
#define _WIN32_WINDOWS 0x0400<br />
#define WINVER 0x0400
If you're willing to drop NT4 support, but retain 98/ME you'd use:
#define _WIN32_WINDOWS 0x0410<br />
#define WINVER 0x0500
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Right, I did understand that part. But what isn't clear to me is the fact that if I would, e.g. drop NT4 support, would the application still work in NT4? Or will it just fail to run?
|
|
|
|
|
If you call a function that is not supported on NT4, your application will fail to start; typically with an entry point not found error (or something similar.)
If you use a structure that is extended for other versions of windows, generally the app will work on NT4, but that function may fail or exhibit odd behavior.
If you use constants that are not meant for NT4, some functions will fail, others will ignore the new constants.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Okay, that's pretty clear. Thanks!
|
|
|
|
|
I am a novice at programming and am working my way through Feng Yuan's book "Windows Graphics Programming". It's great stuff and he includes extensive development of useful graphics classes that can be used in your programs.
Anyway, I'm curious as to why he doesn't use the reinterpret_cast operator in his code when converting pointers. Typically he does something like this:
<br />
GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS);<br />
int nInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader);<br />
int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader);<br />
BYTE * pDIB = new BYTE[nTotalSize];<br />
if ( pDIB )<br />
{<br />
memcpy(pDIB, & dibinfo, nInfoSize);<br />
if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) )<br />
{<br />
delete [] pDIB;<br />
pDIB = NULL;<br />
}<br />
}<br />
ReleaseDC(NULL, hDC);<br />
return (BITMAPINFO *) pDIB;<br />
This is a segment from one of his functions that converts a Device Dependent Bitmap to a DIB (Device Independent Bitmap) which he will later save to file in the Bitmap format. The recasting of pointers is a critical technique to this operation, because when he makes a call later in his program to WriteFile he just supplies the pointer as the parameter.
Anyway, this is from the documantation at the MSDN site:
C/C++ Language Reference
reinterpret_cast Operator
reinterpret_cast < type-id > ( expression )
The reinterpret_cast operator allows any pointer to be converted into any other pointer type. It also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.
I's appreciate any enlightenment on the subject that you can provide, as pointer casting appears to be an operation that could possibly be corrupted. I'm thinking that a special operator could be designed that would be better suited to these types of code transitions.
|
|
|
|
|
As far as I know, reinterpret_cast isn't anything different from a class C-style cast. You can basically turn any pointer into anything else either way.
I'm not sure what you would want with this special operator? But you might want to take a look at dynamic_cast, that might be the one you're looking for. But that only works with polymorphism, and that doesn't work for the WINAPI stuff.
|
|
|
|
|
Thanks for the response. I should have been clearer in my initial question.
The code that Feng Yuan uses works perfectly, but appears cumbersome and even though the compiler will accept the cast, it does no checking of types to insure adequate memory addressing (...but, I'm probably wrong about this). In this case, Feng Yuan casts from a BYTE pointer to a BITMAPINFO pointer (they obviously are the same size or the function would not work). I have not tried this, but, I'm guessing that you could use the same technique with a VOID* (VOID pointer).
More importantly, why even use reinterpret_cast at all? Why does Microsoft even include it in it's Programmer API? This whole subject is a mystery to me. I'm curious as to what instructions the compiler actually issues when such a cast is made.
Also, an assert statement could be made, but Feng Yuan never does. No doubt I'm missing something important here.
This further information from MSDN:
There are several casting operators specific to the C++ language. These operators are intended to remove some of the ambiguity and danger inherent in old style C language casts. These operators are:
dynamic_cast Used for conversion of polymorphic types.
static_cast Used for conversion of nonpolymorphic types.
const_cast Used to remove the const, volatile, and __unaligned attributes.
reinterpret_cast Used for simple reinterpretation of bits.
|
|
|
|
|
I can't tell you as to why using reinterpret_cast instead of C-style casting. Basically it comes down to the same as far as I know, and you could use it for the sake of consistancy. Like if you use stuff like dynamic_cast, static_cast, etc. it would be more consistant to use reinterpret_cast as well.
Maybe this link can enlighten you more: http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=131
|
|
|
|
|
According to Stroustrup[^], part of the reason for adding the various cast operators and making them so syntactically ugly was to make them more noticeable in your code. It's difficult to tell the difference between a 'C'-style cast and a user-defined conversion operator. The '*_cast' operators make those sorts of things easier to see, and more explicit of programmer intent.
Software Zen: delete this;
|
|
|
|
|
reinterpret_cast is the same as the C style cast your writer uses. The compiler does nothing, the cast is a statement from you the programmer that the types are equivalent. In this case they are. It would be better style to use reinterpret_cast but the code in question isn't modern C++, rather it's C with a few C++ bits, so the C style class seems appropriate.
The other C++ casts are more constraining and allow the compiler to determine whether what you (or a user of your code) are trying to do is appropriate.
Paul
|
|
|
|