|
Joe Woodbury wrote: The point is that you could do *(int*)ptr.
is working fine,
But I want to print array so I tried following code which is not working,
So can you please make it workable.
int arr[]={10,20,3,6};
void *ptr=(void *)arr;
int i=3;
while(i--)
{
printf(" %d",(*(int *)ptr));
(int *)ptr+=2;
}
|
|
|
|
|
I don't understand why you are using a void*. It has no concept of size of what it's pointing to. You are removing type safety for no reason.
That said, when you increment do arithmetic on a pointer, that arithmetic is done according to the size of the object pointed to by that pointer. In this case you are casting ptr to an (int*). Therefore, you only need to increment ptr by 1 to take you to the next position. (As an aside, (int*)ptr += 1; will not compile on many compilers--you would have to have ptr = (int*)ptr + 1;
Two other points:
You don't need to cast arr to a void*, that cast is automatic.
You have an off by one error; you have four items in your array, but you only go through the loop three times.
You simply shouldn't be using a void* in a case like this. It's an extremely bad idea. It would be better to use arr[] directly or if you must use a pointer, use an int*.
|
|
|
|
|
Joe Woodbury wrote: I don't understand why you are using a void*
Just I wanted to check that is is possible to print array using void*,
You helped me a lot and I Could, thanks.
Last one Q.:
ptr = (int*)ptr + 1;
In this case,I don't understand why you incremented by 1, size of int is 2,
ptr is void* but we are converting it into int so suppose to be incremented by 2; but it fails and how above code works fine ?
|
|
|
|
|
The size of an int varies by compiler and platform. On 16-bit operating systems, it is 16 bits or 2 bytes long. On 32-bit operating systems, it is 32 bits or 4 bytes long.
Incrementing a pointer will cause it the memory reference to increase by the size of the object it points to. One way to look at pointers is to understand that int* pArray is functionally equivalent to int array[4] . Likewise, assuming that pArray points to array, pArray[0] is the same as array[0]. Likewise pArray[1] is the same as array[1]. pArray[1] is the same as *(pArray + 1).
|
|
|
|
|
Hello,
I am trying to assign an array to a range in Excel. I am using Excel 2007, Visual C++, MS VC++2008 Express Edition on XP.
I have read a number of articles from MSDN and other places to get started, but I continue to get run-time errors.
The basic logic is:
1. Identify a range pointer (type RangePtr) defined for a specific range in an existing Excel spreadsheet.
2. Create a BSTR.
3. Put the BSTR in a one element SAFEARRAY (two dimensions, one row, one column).
4. Wrap the SAFEARRAY into a VARIANT.
5. Assign the VARIANT to the RangePtr.
The code compiles without errors, but I get run-time errors when using the last step. I get no run-time errors if I omit the last step (step #5).
The call stack that results when running the program:
kernel32.dll!7c812aeb()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
kernel32.dll!7c812aeb()
kernel32.dll!7c809ac6()
InterfaceWithExcel.exe!_com_raise_error(HRESULT hr=-2147352568, IErrorInfo * perrinfo=0x00000000) Line 19 C++
InterfaceWithExcel.exe!_com_issue_error(HRESULT hr=-2147352568) Line 39 + 0xe bytes C++
> InterfaceWithExcel.exe!_com_util::CheckError(HRESULT hr=-2147352568) Line 99 C++
InterfaceWithExcel.exe!_variant_t::_variant_t(const tagVARIANT & varSrc=safearray of BSTR = [1,1](0x001a4bf4 "C")) Line 1136 + 0x1d bytes C++
InterfaceWithExcel.exe!main() Line 98 + 0x12 bytes C++
InterfaceWithExcel.exe!__tmainCRTStartup() Line 582 + 0x19 bytes C
InterfaceWithExcel.exe!mainCRTStartup() Line 399 C
kernel32.dll!7c817067()
Googling has told me that hr=-2147352568 means "bad variable type." But I don't know where the bad variable type is in the code below. You can see above how the code does see my one element SAFEARRAY with the BSTR value of "C". (This is bstr1, defined in the code below.)
I have been successfuly in assigning values to individual cells. So the code is not entirely on the wrong track. For example, myRangePtr->Item[1][1] = 1; will successfully assign the number 1 to cell A1. But I'm trying to dump an entire table, and so I would like to be able to assign arrays to ranges rather than cell values one at a time.
The code follows below.
Thank you for your time!
--Matt Pugsley
#import \
"C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL" \
rename("DocumentProperties","DocumentPropertiesXL") \
rename("RGB", "RGBXL")
#import \
"C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\OFFICE12\EXCEL.EXE" \
rename("DialogBox", "DialogBoxXL") rename("RGB", "RGBXL") \
rename("DocumentProperties", "DocumentPropertiesXL") \
rename("ReplaceText","ReplaceTextXL") \
rename("CopyFile","CopyFileXL") \
exclude("IFont","IPicture") no_dual_interfaces
#include <iostream>
using std::cout;
using std::endl;
#include <cstdlib>
int main()
{
Excel::_ApplicationPtr XL;
HRESULT hr;
try
{
CoInitialize(NULL);
XL.CreateInstance(L"Excel.Application");
XL->Visible = true;
}
catch(_com_error &error)
{
cout << "COM error " << endl;
}
XL->Workbooks->Add(Excel::xlWorksheet);
Excel::_WorksheetPtr pSheet = XL->ActiveSheet;
Excel::RangePtr pRange = pSheet->Cells;
Excel::RangePtr pBeginRange = pRange->Item[1][1];
Excel::RangePtr pEndRange = pRange->Item[1][1];
Excel::RangePtr pTotalRange = pSheet->Range[(Excel::Range*)pBeginRange][(Excel::Range*)pEndRange];
wchar_t wsz1[] = L"C";
wchar_t wsz2[] = L"D";
BSTR bstr1;
bstr1 = ::SysAllocString(wsz1);
BSTR bstr2;
bstr2 = ::SysAllocString(wsz2);
SAFEARRAYBOUND rgsabound[2] = { 0 };
rgsabound[0].cElements = 1;
rgsabound[0].lLbound = 0;
rgsabound[1].cElements = 1;
rgsabound[1].lLbound = 0;
SAFEARRAY* mySafeArrayPtr = SafeArrayCreate(VT_BSTR,2,rgsabound);
long index[2];
index[0] = 0;
index[1] = 0;
hr = SafeArrayPutElement(mySafeArrayPtr,index,bstr1);
VARIANT var;
VariantInit(&var);
var.vt = VT_ARRAY ;
var.parray = mySafeArrayPtr;
pTotalRange->Value = var;
SysFreeString(bstr1);
SysFreeString(bstr2);
hr = SafeArrayDestroy(mySafeArrayPtr);
return 0;
}
|
|
|
|
|
I've gotten the code to assign an array to an Excel range, as desired, but now I'm getting errors regarding the native COM capabilities built into VC++2008. They regard releasing some interface pointers. I expect it's because I've pulled my code from many different sources: some using MFC, some not; some using #import directives, some using explicit references to IDispatch.
I'll just keep grinding on it.
Thanks,
Matt
Here's the current code in case anyone else is working on a similar project and wants an example that *almost* works.
#import \
"C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL" \
rename("DocumentProperties","DocumentPropertiesXL") \
rename("RGB", "RGBXL")
#import \
"C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\OFFICE12\EXCEL.EXE" \
rename("DialogBox", "DialogBoxXL") rename("RGB", "RGBXL") \
rename("DocumentProperties", "DocumentPropertiesXL") \
rename("ReplaceText","ReplaceTextXL") \
rename("CopyFile","CopyFileXL") \
exclude("IFont","IPicture") no_dual_interfaces
#include <iostream>
using std::cout;
using std::endl;
#include <cstdlib>
int main()
{
Excel::_ApplicationPtr XL;
HRESULT hr;
try
{
CoInitialize(NULL);
XL.CreateInstance(L"Excel.Application");
XL->Visible = true;
}
catch(_com_error &error)
{
cout << "COM error " << endl;
}
XL->Workbooks->Add(Excel::xlWorksheet);
Excel::_WorksheetPtr pSheet = XL->ActiveSheet;
Excel::RangePtr pRange = pSheet->Cells;
Excel::RangePtr pBeginRange = pRange->Item[1][1];
Excel::RangePtr pEndRange = pRange->Item[1][1];
Excel::RangePtr pTotalRange = pSheet->Range[(Excel::Range*)pBeginRange][(Excel::Range*)pEndRange];
wchar_t wsz1[] = L"C";
wchar_t wsz2[] = L"D";
BSTR bstr1;
bstr1 = SysAllocString(wsz1);
BSTR bstr2;
bstr2 = SysAllocString(wsz2);
SAFEARRAYBOUND rgsabound[2] = { 0 };
rgsabound[0].cElements = 1;
rgsabound[0].lLbound = 0;
rgsabound[1].cElements = 1;
rgsabound[1].lLbound = 0;
VARIANT arr;
arr.vt = VT_ARRAY | VT_BSTR;
arr.parray = SafeArrayCreate(VT_BSTR,2,rgsabound);
long index[2];
index[0] = 0;
index[1] = 0;
hr = SafeArrayPutElement(arr.parray,index,bstr1);
pTotalRange->PutValue2(&arr);
VariantClear(&arr);
SysFreeString(bstr1);
SysFreeString(bstr2);
CoUninitialize();
return 0;
}
|
|
|
|
|
Its a such a nice code its working fine.
but on some machine its not working fine.
its generate execption on this line
Excel::RangePtr pRange = pSheet->Cells;
please help me how can i solve its.
thanks in advance.
|
|
|
|
|
I would like to change the ARROW pointer to HAND (or CROSS) pointer in runtime without any physical event (no Button, Menu ...) triggered. I use this function to invoke new pointer type but it doesn't work:
void ChangePointerType(int type)
{
if(type == 0)
{
HCURSOR hCursor = LoadCursor(NULL, IDC_ARROW);
SetCursor(hCursor);
}
else if(type == 1)
{
HCURSOR hCursor = LoadCursor(NULL, IDC_CROSS);
SetCursor(hCursor);
}
else if(type == 2)
{
HCURSOR hCursor = LoadCursor(NULL, IDC_HAND);
SetCursor(hCursor);
}
ShowCursor(true);
}
Thank to any help?
|
|
|
|
|
Not exactly sure what you want to achieve but look at WM_SETCURSOR[^].
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
I did try as you suggested & it works! However, I forgot to mention that I would like to change the Pointer shape entirely ... with this method, I only can change the Pointer when my Pointer move across my GUI! If it moves out of the GUI, it returns to the default shape!
By any chance, MFC (VC++) can do the above just mentioned?
Thanks for help
|
|
|
|
|
I'm not sure if that is possible or not...why do you want to change the mouse pointer for the whole system? Other applications might want the mouse pointer to have a different shape when it is over them...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
You may want to consider the following from
http://winapi.freetechsecrets.com/win32/WIN32SetCursor.htm[^]
"If your application must set the cursor while it is in a window, make sure the class cursor for the specified window's class is set to NULL. If the class cursor is not NULL, the system restores the class cursor each time the mouse is moved."
I've had this problem in the past. I was changing the cursor when I pressed the left mouse button. When processing the WM_LBUTTONDOWN message, I would use the SetCursor() function. But as soon as I released the mouse button, the cursor would be restored. The problem was that I had a default cursor assigned, and my cursor was reverting to this default as soon as processing for that message was completed. I could 'keep' the new cursor only by continually sending WM_LBUTTONDOWN messages.
You might check your class definition to see if you have a default cursor set.
|
|
|
|
|
Thank for the reminder & the helpfull link, it really help a lot!
|
|
|
|
|
Hi,
I have an SDI application and in view class, I call a dialog by using dlg.DoModal(); There is an EditBox in the dialog and I want to use the entered value in the view class.
Now one way is that I declar a global variable and store the value in it. or declare a varibale in App class and use that variable.
Is any other fine way to do the stuff and I may avoid variable at application level/global?
THANKS
|
|
|
|
|
something like this ?
void CMyView::SomeFunc()
{
CMyDialog dlg;
if (dlg.DoModal() == IDOK)
{
m_myVar = dlg.m_editVar;
}
}
|
|
|
|
|
You can also pass the old value to its constructor as the initial value and make a "Get" method in the dialog class to return the new value.
|
|
|
|
|
|
void CMyView::SomeFunc()
{
CMyDialog dlg;
if (dlg.DoModal() == IDOK)
{
m_myVar = dlg.m_editVar;
}
}
This works fine for OK button but does not work for other buttons such as Connect having id IDCONNECT... any idea why?
if (dlg.DoModal()==IDCONNECT)
{// does not work
}
|
|
|
|
|
Hi all,
I am making my application unicode supporting one. i am using visual studio 2008.
when i try to write texts available as columns in my application in to a file using fwrite function, i am getting values like this..
239††††††††먠몭몭몭몭 test†††††††††††††††††††먠몭몭몭몭몭몭몭몭몭".. actually my column values are "239 test".
Can anyone help me why this is coming and how to get rid of this?
Code Snippet:
fwrite(Currentrow, Currentrow.GetLength()1, f) where Currentrow is CString...
Please let me know if am unclear...
Thanks,
Rakesh.
|
|
|
|
|
First thing is: If you're using MFC, why not use the CFile class instead?
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
Hi,
Is there a way to programmatically change the column width of CMFCPropertyGridCtrl?
|
|
|
|
|
Hi all,
I want to Read and Write to Microsoft Excel with xls and xlsx format.
i have read an article which works fine but its not support XLSX files.
BasicExcel - A Class to Read and Write to Microsoft Excel[^]
i want to read and write xlsx type files also.
please help me for this.
provide me any guidance and any example for xlsx files.
thanks in advance.
To accomplish great things, we must not only act, but also dream;
not only plan, but also believe.
|
|
|
|
|
|
I dont want to use any database or ODBC,please suggest me any other option for this.
thanks in advance.
To accomplish great things, we must not only act, but also dream;
not only plan, but also believe.
|
|
|
|
|
|