|
CreateBitmap()
You may be right
I may be crazy
-- Billy Joel --
Within you lies the power for good - Use it!
|
|
|
|
|
You beat me to it - but I plugged your image viewer helper app!
Iain.
|
|
|
|
|
HBITMAP CreateBitmap(
int nWidth,
int nHeight,
UINT cPlanes,
UINT cBitsPerPel,
CONST VOID *lpvBits
);
Have a look at the CreateBitmap (shocking name, I know) command - you can specify a pointer to data which will make up the bitmap. There are some issues with it - you'll need the data to match the bits per pixel, etc.
Or CreateDIBitmap may be better for you.
You'll have to transform you data into a format those command will be happy with though - and how hard that is depends on how "friendly" your format is.
If you search codeproject by author for PJ Arends, you can use his Image Viewer article to help you. It's great if you're fiddling about with DCs, and Bitmaps - it's saved hours of development for me in the past.
Iain.
|
|
|
|
|
I create an abstract class and a class derived from it. I know that an abstract class's object cannot be created until all its pure virtual functions are redefined within their derived class. However, How about the constructor and destructor functions? As they are special class functions, they can not be redefined within their derived class.
class Abstract_base {
public:
virtual ~Abstract_base()=0;
virtual void interface1() const = 0;
virtual const char* mumber() const
{
return _mumble;
};
protected:
char *_mumble;
};
class Concrete_derived : public Abstract_base {
public:
Concrete_derived()
{
};
virtual void interface1() const {};
};
int main
{
Concrete_derived trouble;
return 0;
}
The code above has link eror.(error LNK2019)
If I change "virtual ~Abstract_base()=0;" to "virtual ~Abstract_base()=0; {}", the link error disappeared. Why shall we add "virtual" to the destructor function?
Can you give me some explanation?
many thanks
Tomorrow is another day!
|
|
|
|
|
You shouldn't put a =0 after your destructor. This means that the function is a pure virtual function: the function be implemented by all child classes. It is quite odd to put that on a destructor.
A destructor is always required (one is supplied by default if you don't write it yourself) so, you need to provide a body. Which you did by adding {} . This is just an empty body, but it is still a body.
If you don't provide a body for your destructor, you'll get a linker error.
|
|
|
|
|
Cedric Moonen wrote: It is quite odd to put that on a destructor.
What? It is exactly what any abstract base class should have. Did you ever read Effective C++ by Scott Meyers?
|
|
|
|
|
led mike wrote: Did you ever read Effective C++ by Scott Meyers?
Nope but I was planning to buy it soon
led mike wrote: It is exactly what any abstract base class should have.
Yes, I see. I never done it that way: I always used at least one pure virtual function.
|
|
|
|
|
richardye wrote: Can you give me some explanation?
You must provide a definition of the pure virtual destructor.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Destructors *are* different from normal memeber functions. If you have a normal member function, you can choose whether to call the ancestor's implementation or not.
eg:
void CMyDialog::DoDataExchange (CDataExchange *pDX)
{
....
CDialog::DoDataExchange (pDX);
}
While it's good practise to call the ancester method in the example above, it's not required to by C++ - so DoDataExchange could have been a virtual =0 member.
BUT...
Destructor's don't get the choice of whether to call the ancester destructor or not. When CMyDialog::~CMyDialog is finished, CDialog::~CDialog is run whether you want it or not. In which case, it needs to exist - even if it's very boring (eg { } ) as you've found out.
I hope that helps a little.
Iain.
|
|
|
|
|
You mean that no matter how I should define the pure destructor function.
But there is still something I cannot understand very well.
If in your class you have a pure member function, you must show that any class derived from it should implement your pure function. Isn't it?
But if you define a destructor function to be pure, you cannot implement it in your derived class and you have to add "{}" in your base class. I think it is meaningless. Why shall we use pure destructor function in a class?
Many thanks.
Tomorrow is another day!
|
|
|
|
|
Hi all.
In a program I am currently writing, I would initiate to add some functions based on a right-click of a particular edit control. However, CEdit catches the OnRClick event itself, in order to build a pop-up menu of its own (with stuff like "copy", "paste", etc). Is there a way in which I can add my own items to this pop-up menu? (and of course, respond to them within the CEdit's parent) If not, I would like to send a NM_RCLICK notify message to the parent, overriding the CEdit's OnNotify handler, so that the parent can build its own pop-up menu, and leave the CEdit's pop-up menu unused. However, when doing so, how do I get the control's id (since I need to put this in the NMHDR structure in order to identify the control that sent the notification message).
Any help would be very much appreciated.
Regards,
William
|
|
|
|
|
William Engberts wrote: However, when doing so, how do I get the control's id
GetDlgCtrlID() ?
|
|
|
|
|
|
|
Thanks a lot! I am continuing work based on your article.
Regards,
William
|
|
|
|
|
Hello,
I have Microsoft Excel 2003 and want to open in VC++ through CreateDispatch() method of _Application .
_Application app;
app.CreateDispatch("Excel.Application");
With the above I get an error.
What is the parameter that I should use in CreateDispatch() or what are the files that I should check in my directory which are necessary to run _Application.
Pritha
|
|
|
|
|
Hi Pritha,
You should preceed your code with "CoInitialize (NULL);". Next to this, it is better in my experience, to check is Excel is already running and use the running instance of excel if it is. Only start a new instance if no excel is running. I use the following routine:
BOOL OpenExcel (LPCTSTR szFilename)
{
_Application Excel;
BOOL bExcel = FALSE;
CLSID clsid ;
LPDISPATCH lpDispatch ;
LPUNKNOWN lpUnk ;
HRESULT hr;
COleException * Error = new COleException;
CoInitialize (NULL); // We must be initialized first!
//------------------------------------------------------------------------------------
// Check if Excel is already running
//
if (CLSIDFromProgID(OLESTR("Excel.Application"), &clsid) == NOERROR)
{
if (GetActiveObject (clsid, NULL, &lpUnk) == S_OK)
{
hr = lpUnk->QueryInterface(IID_IDispatch, (LPVOID*)&lpDispatch) ;
lpUnk->Release() ;
if (hr == NOERROR) // Yep, excel is already there
{
Excel.AttachDispatch (lpDispatch, TRUE) ;
bExcel = TRUE;
}
}
}
if (!bExcel) // Excel was not yet running
{
bCreated = TRUE; // we now created an instance of Excel ourselves
bExcel = TRUE; // start from a positive assumption
try
{
if(!Excel.CreateDispatch("Excel.Application",Error)) // Create the instance
throw Error; // throw an error on failure
}
catch (COleDispatchException * Error) // Oops... could not create...
{
CString strMessage;
strMessage = "Could not launch Microsoft Excel\r\n";
if (!Error->m_strSource.IsEmpty())
{
strMessage += Error->m_strSource;
strMessage += " - ";
}
if (!Error->m_strDescription.IsEmpty())
strMessage += Error->m_strDescription;
else
strMessage += "unknown error";
MessageBox (HWND_DESKTOP, (LPCTSTR)strMessage, NULL, MB_OK|MB_ICONERROR);
bCreated = FALSE; // no Excel created afterall
bExcel = FALSE; // and no Excel running....
}
}
Error->Delete (); // we do not need the Error exception
return bExcel;
}
|
|
|
|
|
Hello,
Your code above was useful.I wanted to find out how many rows should be read from the sheet.For that I have used the following but it doesn't work.
LPDISPATCH lpDisp;
lpDisp = sheet.GetUsedRange();
range.AttachDispatch(lpDisp);
range.Select();
range.GetRows();
long lTotalRows = range.GetCount();
Any ideas
Thanks
Prithaa
|
|
|
|
|
Hello Prithaa,
I am not sure, but I think the following should work (did not test it though)
Range Rng;
Range Rws;
Rng = Sheet.GetUsedRange ();
Rws = Rng.GetRows ();
long lTotalRows = Rws.GetCount ();
Rws.ReleaseDispatch ();
Rng.ReleaseDispatch ();
There is no need to use a separate LPDISPATCH and then connect it to a Range variable; you can do this directly as above.
Regards,
William
|
|
|
|
|
Hello everyone,
I think printf %d works fine with signed, unsigned and negative integer values, and the same as %ld for long. Is that correct? If not, do we need to special conversion?
thanks in advance,
George
|
|
|
|
|
Hi George,
Yep, you are right. Although I must say that in today's implementation there is no difference between int and long (they both are 4 bytes)
William
|
|
|
|
|
Thanks William!
regards,
George
|
|
|
|
|
I tried with
long int li = 0xFFFFFFFFL;
unsigned long int uli = 0xFFFFFFFFL;
printf( "%ld %ld\n", li, uli );
short int si = 0xFFFF;
unsigned short int usi = 0xFFFF;
printf( "%d %d\n", si, usi );
And the result was
-1 -1
-1 65535
- NS -
|
|
|
|
|
Thanks NS17!
I am clear.
regards,
George
|
|
|
|
|
Hi All,
I have an application which updates itself when new version is available . But thises updates are having a problem if the app is run by a user having non admin rights , as the service alters the files in %program Files% folder , registry settings while updating . if the user is a non admin then these processes fail and thus the update fails . Is there any way by which i can find if the logged in user is a administrator or not ? so that i dont allow updates for a non admin user ???
Thanks in Advance
Vijayeta
|
|
|
|