|
m_YourEdit.EnableWindow(0)
GetDlgItem(IDC_EDIT1)->EnableWindow(0)
whitesky
|
|
|
|
|
gourav456 wrote: so i want to know when i click on menu command from one dialog box it will open other dialog box and some edit boxes are disabled which i made earily
plz give me ans quickly
thanks for ur ans in adv
Is second Dialog Box is modeless or Model!
if it model :-
Then Set some Boolean variable which enable or disable the Button on the basis of boolean values
if is Modeless
you can post message to dialog box to enable or disable it button state
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
Hello everyone,
I am confused about the term "stack" which the system will use -- there are so many items we call them "stack". Suppose when we invoke a function, we will push the parameters and return address into a "stack", so that when the function returns, it can find the address to proceed correctly. Is it the same as a data structure "stack".
When we create a variable using malloc or new, we also say that it is allocated on "heap" other than on "stack", is heap also something like a stack in ternally (but has a different term)? And for local variables, when they are created, we say it is created on stack (for example, int i, j; ), it seems that each function has a separate stack?
Another confusing thing is thinking about stack and segment together, like the code segment, data segment of the program (which you can see when debugging your application), are the segments also some stacks (since when local variables are on code segment, we also say local variables are on stack, so I think maybe segment is implemented as stack)?
Besides the "stacks" I presented above, are there any other stacks which system will utilize?
Please forgive asking a simple question.
regards,
George
|
|
|
|
|
My viewpoint is the following:
When you start a C++ program, it consists of four parts: the code segment, the data segment; a unique heap area; a unique stack area.
The code segment contains microprocessor instructions obtained after successful compilation.
The data segment contains at least data declared with "static " modifier, as well as quoted strings.
When you call a function, for instance "f(1,2,3) ", then the arguments 1, 2 and 3 are pushed on the stack (the particular order depends on some factors). Also a return address (the address of the next instruction, after your "f(1,2,3) ") is pushed on the stack. Within the function, when you access an argument, you actually access a value from the stack. When the function finishes and returns back to the pushed address, the pushed values are popped from the stack and are lost, and the stack returns to its previous state.
Push and pop operations are performed by microprocessor using special pointer, stored in a register, which points to the top of the stack.
If you call a function again, the same stack is re-used.
If you have some local variables in your function, they are allocated on the same stack, somewhere above the pushed parameters and return address. That’s why you can crash your program if you access local variables incorrectly. For instance, by accessing a local array using invalid index.
Local variables declared with "static " modifier are allocated in data segment instead of the stack. This way, the value of static local variables is preserved between function calls.
If you call functions recursively, or use too large local variables, the stack becomes full.
When you use new operator or malloc function, data are allocated from the heap area. In contrast with the stack area, which are automatically cleared back when you return from a function, the heap-allocated data must be release explicitly, using delete or free .
If you allocate too much data or forget to release unneeded ones, the heap area becomes full. If you uses invalid pointers, you can corrupt the heap area.
So, there is a single stack and a single heap shared by your functions, and each program has its own stack and heap.
Windows applications also can allocate data in a specific manner using system functions like GlobalAlloc and others.
That is my vision on stack and heap.
|
|
|
|
|
Thank you Viorel,
> "each program has its own stack and heap"
Do you mean each process will has one unique stack and unique heap? So, different threads in the same process will share the stack and heap?
In your reply, you have never mentioned global variables and const variables. Will they be on data segment or on heap?
regards,
George
-- modified at 7:42 Monday 5th June, 2006
|
|
|
|
|
In multithreading application each of the thread in the same process will have its own stack. (That's why the functions like CreateThread or _beginthread have an optional argument for stack's size).
But the heap area is common for all of the threads. As a result, access to common heap data, as well as to common data segment, must be "synchronized". When you build multithreading applications, it is important to specify the correct compiler options (like "Runtime library"), otherwise shared data will be unexpectedly corrupted.
Global and constant variables are allocated in data segment. Actually this segment can be divided into constant data and changeable data. Compiler can apply some microprocessor’s or OS features in order to detect violation of constant data.
|
|
|
|
|
Thank you very much Viorel!
I am a further question, as you mentioned before, each process will have a separate heap. So, if I use new operator on different process, they will be allocated on different heap. Correct? (a little more conflicts with my previous understanding, since I think new operator will access the same memory range to find an empty slot for different processes -- the range is common to all processes -- to allocate space, so the space allocated by new for different process may be next to each other).
> "When you build multithreading applications, it is important to specify the correct compiler options (like "Runtime library"), otherwise shared data will be unexpectedly corrupted."
I understand that synchronization control between threads are important. But I have not found any relationship between your above statements and synchronization control between threads. What are your points in above statements?
regards,
George
-- modified at 8:27 Monday 5th June, 2006
|
|
|
|
|
Each process has its own "memory space". From one process, you cannot easily access data from another process. As a result, when you use new operator, you obtain a memory fragment which belongs to this process only.
Even if in one process the pointer returned by new operator is, for example, 0x30000, it is possible that another process will get the same value in its new call. But changes made in one process via this pointer do not affect another process. This is because of separated memory spaces. So the 0x30000 address in both processes points to different "physical locations". On microprocessor/system level, there is an automatic procedure for conversion between pointer's values ("virtual address") to "physical address". For instance, the 0x30000 address is converted to the 0x7800000 physical address in the first process, and to 0xAB00000 physical address in the second one, from your, let's say, 1 GBytes of memory.
Also it should be considered that if a process requests more memory that physically is available, then some parts of other processes can be temporary discarded to disk. Probably this is what is called "paging file".
C++ libraries usually are delivered in both versions -- for single-threaded and multi-threaded application. This is for performance reason: single-threaded application does not require redundant synchronization. For instance, there is a version for new operator for single-threading, and another for multi-threading. I just wanted to point that the system functions for single-threading will usually not work in multi-threading mode, so the proper compiler configuration is required in order to avoid heap corruption.
For your own functions, you have to provide your own synchronization. In Windows, there is a series of objects ("critical section", "mutex", etc.) for doing this.
|
|
|
|
|
Thank you Viorel!
Your reply is excellent!! I think both data segment and heap are used to provide global access through a process (that is, compared with stack, variable will disappear when function returns, but in data segment or in heap, variable will be valid and accessible through the life-cycle of a process). My question is that, why system needs to divide global data access through a process into data segment and heap -- they are both used for the same purpose (global data access through a process), what are the different functions between them?
regards,
George
|
|
|
|
|
Data segment is a storage for named variables, declared like "int x = 0; " or "static int x = 0; " outside functions, or as "static int x = 0; " inside functions. Data segment also stores initial value of arrays, like "Hello, World!" for strings, or {1, 2, 3} for integer arrays. This data segment is allocated once, when process starts, and the number of variables here cannot grow.
(One more thing which is stored in data segment is "virtual tables" of classes having virtual functions).
Heap area is for unnamed variables, allocated only when you explicitly call new or related. So the number of variables varies here during program execution.
While variables declared in global data segment can be accessed by name, the variables allocated in heap have to be accessed by pointers or references.
So the main difference between global data segment and heap is that the size of data segment is fixed, while the data allocated in the heap can vary.
That is my understanding.
|
|
|
|
|
Thank you Viorel!
I agree with all of your great points. Except that, you think we do not access the variable on heap by its name. I think all types of variables are accessed by name.
For example,
int* pi = new int [5];
variable pi is allocated on heap, but later when we want to access this variable, we also use the variable name "pi", right? Why you say we do not access variable by its name if the variables are on heap?
> "Heap area is for unnamed variables"
regards,
George
|
|
|
|
|
In declarations like
int * pi = new int[5];
you actually have two variables. First is pi , which is a pointer. It is allocated on the stack (in case of functions) or in data segment (if is outside of functions). The size of pi is usually four bytes. Another variable is the array allocated by new in heap area. This variable has no name, by has an address (for instance 0x1234 ), returned by new , which is assigned to the pi variable. The size of this array is twenty bytes.
Therefore the content of the pi variable is the address of the array, but not the content of array. When you use pi , you actually denote the address -- 0x1234 . For instance, when you call a function, f(pi) , you pass the 0x1234 value to the function, but not the content of array.
When you use delete pi , the unnamed array is deleted, but the pi variable is still available for another assignments.
In order to work with the referenced values via pointer, you use expressions like pi[3] or *(pi+3) .
Actually, in case of data allocated on the heap, you can simulate an assignment of a name, using references. For instance:
int * z = new int;
int & r = *z;
In this case, r is a synonym for the integer allocated on the heap, and the usage of r will be treated as an access to this integer. For instance, r = 200 will assign a new value to that integer. Here, z still denotes an address, but r denotes the value on the heap. So, now that integer has a name -- r ;
Internally, references are stored as pointers, i.e. they contain addresses of referenced variables. They are a convenient way for working with addresses, because "r " is simpler than "*z ".
Therefore we can say that references offer a way for assigning names to variables allocated on the heap.
That is the picture in my opinion.
|
|
|
|
|
Thank you Viorel!
You have answered all of my questions!
regards,
George
|
|
|
|
|
I know this isn't really a C++ question, but Quaternions are commonly used by many C++ coders so I'll ask this here...
I am trying to rotate object A by the reverse of object B's orientation, where I know the orientations of each in quaternion form.
I can do this by converting the quaternion B to a matrix and multiplying A by the inverse of Matrix B, but this seems like a waste or processing power.
What other methods can I use to reverse the rotation of a Quaternion? Would negative scaling work?
When I die I'd like to go peacefully in my sleep like my father, not screaming in terror like his passengers!!!
|
|
|
|
|
Im developing a C++ software on winXP that send and receive SMS using serial port GSM modem..
my stucture now is using two threads ..
1.The first one to write to port and other operations(buttons,funs,..)
2.The second one is to read from port ,it blocks untill there is some thing to be read.
now I want my program to show a message whenever there is a new SMS(the modem notify when there is new SMS automaticilly)
should I make another thread to check the buffer after its read from the reading thread?
or should i implement the check inside the reading thread?
remember that checking for new SMS would be blocking the thread its in sinse its implemented in while loop and/or WaitForSingleObject (using events)
any suggestions?
thanks...
|
|
|
|
|
I see two options.
1. Have the receiving thread post a message to your UI thread to process the received SMS message data and display your information.
2. Separate the UI thread from the serial reading thread AND make another thread for writing. Then you have a UI thread and two worker threads. Either worker thread can notify the UI thread, which would rarely be blocked on any communications issue, of actions to take, such as processing the received SMS message.
What I typically did in COM applications was to have two thread-safe buffers, one for reading and one for writing. My UI thread would post data into the
'output' buffer and signal the serial output (writing) thread data was ready for writing. The serial input (reading) thread would post data to an 'input' buffer, and then signal the UI thread that input data was ready to be processed. Worked really well and kept the UI responsive.
I've seen better runs in my shorts! - Patches O'Houlihan
|
|
|
|
|
Does event socket model have to wait for events in another thread in an interactive app?
|
|
|
|
|
if ur lengthy question can put in a subject, then no need of Body for a thread.
Codeproject Admins pls remove this option.
Make clear ur question with apropriate subject and question.
SaRath.
"Don't Do Different things... Do Things Differently..."
|
|
|
|
|
|
Hi, there,
I added a spin button in my dialog and its name is IDC_SPIN_TAP. Its property is
UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS
I added a class variable CSpinButtonCtrl m_wndSpinTap in the header file. In the cpp file,
<br />
DDX_Text(pDX, IDC_EDIT_TAP, m_nTapNum);<br />
DDV_MinMaxInt(pDX,m_nTapNum,0,100000);<br />
DDX_Control(pDX, IDC_SPIN_TAP, m_wndSpinTap);<br />
......<br />
m_wndSpinTap.SetRange(0,100000);<br />
where IDC_EDIT_TAP is its buddy control. When I clicked the up-arrow of the spin button, the number in the buddy edit window was supposed to increase by one like 0,1, 2, 3.... But strangely, the number becomes 0, -1, -2, -3.... When I clicked the down-arrow of it, the number changed from -3, -2, -1, and stops at zero. How could this happen? Did I miss any setting for the spin button?
Thank you very much!
David
|
|
|
|
|
SetRange() has a maximum range of 32676, use SetRange32() instead.
You may be right
I may be crazy
-- Billy Joel --
Within you lies the power for good - Use it!
|
|
|
|
|
Yeah, solved. thank you very much!
David
|
|
|
|
|
I have a grid that is populated by a recordset that contains the result of a query. When I have a large database (about 80,000 records and above..) it takes a few minutes to load the grid with all of the records. And I need to make this faster...
What I thought to do is load the data page by page, and display 400 records in each page. So, it would work this way: display 400 records, then display another 400 (800 total), and so on until I reach 78000 records.
But I don't know how to actually implement this...
Do I have to fill the recordset first with 400 records, then with 800 records, then with 1200 records, etc and eventually with 78000? Or maybe I can use a number of recordsets - and if so how do I do this?
|
|
|
|
|
Hi guys,
I am using DirectX functions ( Back Surface - primary surface concept & Blt functions ) for clip image ( 300 image frames, which are continuoulsy displayed one after other ) display in a dialog based application. The problem is that, when the movie frames are displayed in a machine having Martox G400 series card, it is getting better performance, but when the same application is run in a machine having NVIDIA Mx/M2 400 series card, the performance is very low. Please help me, whether any directx related changes has to be made in the source code or how to solve this problem ?
Velayudhan
|
|
|
|
|
|