|
Thankx got it working
Had a stack overflow but that was the result of
a oversight on my part
thankx Again
|
|
|
|
|
You're quite welcome. Glad I could help.
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
Please tell me if the following is Correct
IF you use DDX_CONTROL there is no need for
using Create/Attach which associates A
Windows Object the CWnd/Cotrol object
|
|
|
|
|
ForNow wrote: IF you use DDX_CONTROL there is no need for using Create/Attach which associates a windows object the CWnd/Control object
Correct. I am actually writing a much longer reply to your previous message which should better help you understand how this all fits together. Hopefully I'll be a little clearer this time
Is this your first MFC application or have you been playing around with it for a while?
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
I am in my 50's and A MainFrame programmer
My backgroud is MVS inetrnals Assembler
I have been trying to develop other skills
since there is a MainFrame Emulator in "C" DOS
That lead me to C then To Windows
Since Most of the replies I receive from
The CodeProject are of the MFC variety
I re-wrote my App in C++
Since I dont work at this (C++ ) its has been a
difficult learning experince
But people like yourself make it easier
Much apreciated
as A follow up question
Where Should the UpdateData(FALSE) be placed
In The ::OnInitDialog method ???
thankx Again
|
|
|
|
|
How can I store address of integer array to void pointer and print array using void pointer?
|
|
|
|
|
sam_psycho wrote: How can I store address of integer array to void pointer
int anArray[1234];
void* pointyThing = (void*)(anArray);
and print array using void pointer?
I don't know of any built-in way to print arrays from a void*, but presumably you can write a function to do it...
MyPrintArrayFunction(pointyThing);
There are three kinds of people in the world - those who can count and those who can't...
|
|
|
|
|
To print array compiler giving error:
I tried following code but It is not working,
int arr[]={10,20,3};
void *ptr=(void *)arr;
printf("%d",*ptr);
So, please any suggestion to print array using void pointer,
And most imp why compiler not allowing above code ..
|
|
|
|
|
printf expects you to pass a value as an argument. By definition you can't resolve a void pointer. Be happy; in the past the compiler wouldn't stop you from being stupid.
(I actually slightly misspoke--the *ptr is simply an error. That said, newer compilers do some rudimentary "sanity" checking of printf arguments. I've never seen how far the compiler goes, but have seen it complain on occasion when I was being dumb.)
modified on Thursday, July 30, 2009 2:35 PM
|
|
|
|
|
Joe Woodbury wrote: printf expects you to pass a value as an argument. By definition you can't resolve a void pointer.
Agree with you..
Joe Woodbury wrote: Be happy;
Here too...
BUT,
Joe Woodbury wrote: in the past the compiler wouldn't stop you from being stupid.
Is this solution to the problem I asked?
|
|
|
|
|
There is no solution except to case the pointer to something that resolves to an integer or long value (which is dangerous of the void* isn't actually pointing to an integer or long.)
The point is that you could do *(int*)ptr .
(I actually slightly misspoke--the *ptr is simply an error. That said, newer compilers do some rudimentary "sanity" checking of printf arguments. I've never seen how far the compiler goes, but have seen it complain on occasion when I was being dumb.)
|
|
|
|
|
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
|
|
|
|