|
Additionally to what Mark said, add some error handling to your application logic... e.g. if a data upload is interrupted in the middle, you might want to repeat or resume a data transfer.
|
|
|
|
|
Good morning... My query is......
After user selects PRINT menu one message box(usr created)will appear.
The message box consists of 2 command button controls.
one is OK and the other is CANCEL.
If the user presses OK it should take snapshot of the background and should create a BITMAP IMAGE without the message box. That means IMAGE shouldn't contain the message box. For this I am calling EndDialog() function. But now the problem message box is creating some empty space in the background and IMAGE is coming with that empty space. But it shouldn't come.
The code is as folows.
After selecting PRINT menu it will execute the following code.... i.e.,
**************************************************************************8
CSwissMessage m_objMsg;
m_objMsg.m_strMSG = "\n\n\nPress Print to Print the Screen or Cancel To Quit";
m_objMsg.DoModal();
****************************************************************************
Know the message box will appear. If the user selects PRINT button it will execute the following code.....
****************************************************************************
void CSwissMessage::OnClickCmdbtnPrint()
{
CSwissMessage::EndDialog(10);
snap();
}
****************************************************************************
void CSwissMessage::snap()
{
CWnd* pWnd = AfxGetApp()->m_pMainWnd;
if (windowtobmp("ShipStatus.bmp",pWnd)==FALSE)
{
MessageBox("ERROR");
}
}
BOOL CSwissMessage::windowtobmp(CString filename,CWnd* pwnd)
{
CWindowDC dc(pwnd);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CRect rect;
pwnd->GetWindowRect(rect);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height()-150);
CBitmap* poldbmp = memdc.SelectObject(&bmp);
memdc.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
memdc.SelectObject(poldbmp);
HANDLE hdib = ConvertDDBToDIB(bmp);
writebmp(filename,hdib);
GlobalFree(hdib);
CString strPrintFilePath = FindPrintFilePath();
HINSTANCE hInstancePrint;//,hInstanceEditor;
hInstancePrint = ShellExecute(this->m_hWnd,"print","ShipStatus.bmp",NULL,NULL,SW_HIDE);
return TRUE;
}
|
|
|
|
|
hi..i am not sure but you try this one....
after ending the message box function CSwissMessage::EndDialog(10);
....and before calling the snap() function you call Sleep(); function for a while....then u call the snap() function...
|
|
|
|
|
Thank u Mani......
I have tried Sleep() also. But it is not working.
|
|
|
|
|
sairam madem wrote: void CSwissMessage::OnClickCmdbtnPrint()
{
CSwissMessage::EndDialog(10);
snap();
}
Modify this to,
void CSwissMessage::OnClickCmdbtnPrint()
{
SendMessage(WM_CLOSE);
snap();
}
Prasad
MS MVP - VC++
|
|
|
|
|
Thank u prasad....
I have tried your code also....
But it is not working.....
Problem might be with ActiveX Controls....
Becoz Background contains ACTIVEX CONTROLS..
|
|
|
|
|
Hi All,
I have a requirement to add a CArray member varibale in my class without including
afxtempl.h in my class header file.
Is there any method to forward delare CArray class?
Thankx in advance.
|
|
|
|
|
VCSharp007 wrote: I have a requirement to add a CArray member varibale in my class without including
afxtempl.h in my class header file
IMHO you cannot satisfy the above requirement.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
VCSharp007 wrote: I have a requirement to add a CArray member varibale in my class without including
afxtempl.h in my class header file.
template<class TYPE, class ARG_TYPE> class CArray;
class SomeClass
{
public:
CArray<float, float>* pFloatArray = 0;
};
|
|
|
|
|
Thanks Nibu.
But I have to use CArray varibale not pointer!!!!
|
|
|
|
|
VCSharp007 wrote: But I have to use CArray varibale not pointer!!!!
No then forward declaration won't work, since classes should know their sizes. Pointer is ok since size will be sizeof a pointer.
Forward declaration just tells the compiler that the class is ok and definition of that is readily available somewhere. So it searches for the given class when code for the parent class is being generated.
Otherwise include "afxtempl.h" in precompiler header file. But then again there will be issues when this header file is being used somewhere else where there is no precompiled header file.
|
|
|
|
|
This is a bad requirement, because than is the dependency unclear.
Remember: Write selfexplaining code, so you dont need to document the code.
You can also include the afxtempl.h in another header. stdafx.h is a good place because, the afxtempl.h wont be change a lot of times.
Greetings from Germany
|
|
|
|
|
I am trying to do it with MSI , but i do something wrong in the code below , publisher names dont always match with product names , can you browse it ?
Function just fills struct :
#define VERSION_LEN 16
#define CODE_LEN 39
#define NAME_LEN 256
#define PUBLISHER_LEN 256
#define PATH_LEN 256
#define MSI_LEN 256
typedef struct _INSTALLED_SOFTWARE_INFORMATION
{
BOOL bManaged ;
BOOL bPerMachine ;
char wszProductCode[CODE_LEN] ;
char wszProductName[NAME_LEN] ;
char lpVersion[VERSION_LEN] ;
char lpPublisher[PUBLISHER_LEN];
char lpPath[PATH_LEN];
char lpMSI[MSI_LEN];
ERROR_DATA errData ;
}INSTALLED_SOFTWARE_INFORMATION ;
int GetInstalledProducts(INSTALLED_SOFTWARE_INFORMATION* pSwInformation,unsigned int* nCount)
{
DWORD dwIndex = 0;
UINT uiStatus ;
char assignment_type[10] = {0} ;
char lpVersion[VERSION_LEN] = {0} ;
char lpProducts[NAME_LEN] = {0} ;
char lpPublisher[PUBLISHER_LEN] = {0};
char lpPath[PATH_LEN]= {0};
char lpMSI[MSI_LEN]= {0};
DWORD cchAssignmentType ;
DWORD cchVersionName ;
DWORD cchPublisher;
DWORD cchProductName;
DWORD cchPath ;
DWORD cchMsi;
for(;;)
{
uiStatus = MsiEnumProducts(dwIndex,pSwInformation[dwIndex].wszProductCode);
uiStatus = MsiIsProductElevated( pSwInformation[dwIndex].wszProductCode,&( pSwInformation[dwIndex].bManaged ));
uiStatus = MsiGetProductInfo(pSwInformation[dwIndex].wszProductCode,INSTALLPROPERTY_ASSIGNMENTTYPE,assignment_type,&cchAssignmentType) ;
if(uiStatus !=ERROR_SUCCESS )
{
switch(uiStatus)
{
// return FALSE ;
}
}
else
{
if(assignment_type[0] == '1' )
pSwInformation[dwIndex].bPerMachine = TRUE ;
else
pSwInformation[dwIndex].bPerMachine = FALSE ;
}
uiStatus = MsiGetProductInfo(pSwInformation[dwIndex].wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProducts,&cchProductName);
strcpy(pSwInformation[dwIndex].wszProductName,lpProducts);
uiStatus = MsiGetProductInfo(pSwInformation[dwIndex].wszProductCode,INSTALLPROPERTY_VERSIONSTRING,lpVersion,&cchVersionName);
strcpy(pSwInformation[dwIndex].lpVersion ,lpVersion);
uiStatus = MsiGetProductInfo(pSwInformation[dwIndex].wszProductCode,INSTALLPROPERTY_PUBLISHER,lpPublisher,&cchPublisher);
strcpy(pSwInformation[dwIndex].lpPublisher ,lpPublisher);
uiStatus = MsiGetProductInfo(pSwInformation[dwIndex].wszProductCode,INSTALLPROPERTY_INSTALLSOURCE ,lpPath,&cchPath);
strcpy(pSwInformation[dwIndex].lpPath ,lpPath);
uiStatus = MsiGetProductInfo(pSwInformation[dwIndex].wszProductCode,INSTALLPROPERTY_PACKAGENAME ,lpMSI,&cchMsi);
strcpy(pSwInformation[dwIndex].lpMSI ,lpMSI);
dwIndex++;
*nCount = dwIndex ;
}
EXIT :
return dwIndex ;
}
|
|
|
|
|
Hi everybody. I got a tiny question about a strange problem I'm having when I'm trying to receive a string from Visual Basic into C++. I got a VB string saying "Arial". But when I'm receiving it in C++, it becomes "Ail". Probably some wide characters versus normal characters problem, as i get 1 character and the next not, and then the next, I get. In order to make the conversion I'm using these two functions.
<br />
<br />
long GetLengthOfBSTR (BSTR Target)<br />
{<br />
long iRet = 0;
long iCursor = 0;
bool bForever = false;
<br />
if (Target == NULL)<br />
return(0);
while (!bForever)
{<br />
unsigned int uiPiece = Target[iCursor];
if (uiPiece == 0)<br />
return(iRet);
else<br />
iRet++;
iCursor++;
}<br />
return -1;
}<br />
<br />
char *ConvertBSTRToChar (BSTR Target)<br />
{<br />
char *sResult;
long iCounter;
long iLength;
<br />
iCounter = iLength = GetLengthOfBSTR(Target);
sResult = new char[iLength + 1];
strcpy(sResult, "");
for (iCounter = 0; iCounter < iLength; iCounter++)
{<br />
unsigned int uiPiece = Target[iCounter];
sResult[iCounter] = uiPiece;
sResult[iCounter + 1] = '\0';
}<br />
return sResult;
}<br />
And then I do:
<br />
LPCSTR c;<br />
c = ConvertBSTRToChar(StuffFromVB);<br />
MessageBox(0, c, "Test", 0);<br />
SO? Anybody here to enlighten me a bit about this? : ). Thank you very much for your time here anyway!
|
|
|
|
|
Why do you have to roll out convertion functions for BSTR's on your own. We already have ConvertStringToBSTR and ConvertBSTRToString . Why not use them. Link to comsupp.lib for using them.
|
|
|
|
|
<br />
LPCSTR d = _com_util::ConvertBSTRToString(FontInformation.Name);<br />
MessageBox(0, d, 0, 0);<br />
This still returns garbage data : ( ... what do you make of: "???r" instead of "Arial". And it's sure that it's a BSTR there. For example, my function works but doesn't process the BSTR correctly. It would be easier for me to fix my function ... if only I knew what's wrong : D.
|
|
|
|
|
Axonn Echysttas wrote: This still returns garbage data : ( ... what do you make of: "???r" instead of "Arial". And it's sure that it's a BSTR there. For example, my function works but doesn't process the BSTR correctly. It would be easier for me to fix my function ... if only I knew what's wrong : D.
Watch memory for this variable to see if the contents is in the variable as you expect it to be.
|
|
|
|
|
Your functions are wrong. Note that a bstr is not required to be null terminated. If you want to get the size of a BSTR, use for example wcslen. To convert between BSTR and C-style strings, use
W2A, OLE2A macros from <AtlBase.h>. Also see CComBSTR class.
--
=====
Arman
|
|
|
|
|
I replaced with wcslen and still same problem. I would prefer to understand how to convert it corectly, manually. That way I don't have to depend on more links and stuff that can break from one windows release to the other : ).
|
|
|
|
|
|
|
Arman Z. Sahakyan wrote: Note that a bstr is not required to be null terminated.
Actually BSTR is terminated by double byte NULL. \0\0
Best Wishes,
-David Delaune
|
|
|
|
|
Hi,
Try using:
<br />
template<class T> BSTR ConvertToBSTR(T a_Str) <br />
{<br />
return(_bstr_t(a_Str).copy());<br />
}<br />
It's the same function I posted in your article two years ago.
Best Wishes,
-Randor (David Delaune)
|
|
|
|
|
Hhahahaah, Hi : D. That should be a lesson to me huh? To better remember stuff.
Hm, however, this is to return a BSTR, I need the other way around. A Char from a BSTR. : D.
|
|
|
|
|
Hi again,
The _bstr_t has a built-in char* operator. So this means you can just do something like this:
<br />
BSTR test;<br />
char buffer[SOME_LENTH];<br />
_bstr_t bstr(test,true);<br />
strcpy(buffer,(char*)bstr);<br />
The above code does not check buffer length. A simple new/delete using the BSTR length should take care of that.
Best Wishes,
Randor (David Delaune)
|
|
|
|
|