|
Ok
thankx on Further inspection I noticed that I had Created The CDialog derived object on the Heap
so .... After DestroyWindow
I "delete CDialogptr" which invokes the destructor ....where I did CDialogptr = NULL
thankx
|
|
|
|
|
Hi all,
I am writing a small win32 application to learn how to shown a popup menu in response to right mouse button click event. I use win32 SDK functions LoadMenuIndirect and TrackPopupMenu and borrow some menu-template-creation code from this link (
http://msdn.microsoft.com/en-us/library/90zx250s(VS.80).aspx).
The problem is that the popup menu is so narrow (looks like a narrow vertical stripe) that the first-level menu item text is invisible. Interestingly, the second-level menu items are shown properly. This issue can be reproduced with my code (PopMenu.c and PopMenu.mak) below. Any help will be greatly appreciated.
Leonard
2009-10-18
// PopMenu.c
#include <windows.h>
#define ID_APP_EXIT 30001
#define ID_EDIT_COPY 30002
#define ID_EDIT_PASTE 30003
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
TCHAR szAppName[] = TEXT("PopMenu2");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if ( !RegisterClass(&wndclass) ) {
MessageBox(NULL, TEXT("This program requires Windows NT/2000/XP!"),
szAppName, MB_ICONERROR);
return 0;
}
hInst = hInstance;
hwnd = CreateWindow(szAppName, TEXT("Popup Menu Demonstration #2"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while ( GetMessage(&msg, NULL, 0, 0) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// This is a helper function for adding a menu item (either a popup
// or command item) to the specified menu template.
//
// MenuTemplate - pointer to a menu template
// MenuString - string for the menu item to be added
// MenuID - id for the command item. Its value is ignored if IsPopup is TRUE.
// IsPopup - TRUE for popup menu (or submenu); FALSE for command item
// LastItem - TRUE if MenuString is the last item for the popup; FALSE otherwise.
UINT AddMenuItem(LPVOID MenuTemplate, WCHAR* MenuString, WORD MenuID, BOOL IsPopup, BOOL LastItem)
{
MENUITEMTEMPLATE* mitem = (MENUITEMTEMPLATE*) MenuTemplate;
UINT bytes_used = 0;
if (IsPopup) { // for popup menu
if (LastItem)
mitem->mtOption = MF_POPUP | MF_END;
else
mitem->mtOption = MF_POPUP;
bytes_used += sizeof (mitem->mtOption);
mitem = (MENUITEMTEMPLATE*) ((BYTE*) MenuTemplate + bytes_used);
// a popup doesn't have mtID!!!
wcscpy((WCHAR*) mitem, MenuString);
bytes_used += sizeof (WCHAR) * (wcslen(MenuString) + 1); // include '\0'
}
else { // for command item
mitem->mtOption = LastItem ? MF_END : 0;
mitem->mtID = MenuID;
wcscpy(mitem->mtString, MenuString);
bytes_used += sizeof (mitem->mtOption ) + sizeof (mitem->mtID) +
sizeof (WCHAR) * (wcslen(MenuString) + 1); // include '\0'
}
return bytes_used;
}
// Create a menu handle from a menu template in memory.
HMENU LoadMenuTemplate()
{
// For simplicity, allocate 500 bytes from stack. May use
// GlobalAlloc() to allocate memory bytes from heap.
BYTE milist[500];
MENUITEMTEMPLATEHEADER* mheader;
int bytes_used;
HMENU hMenu;
memset(milist, 0, 500);
// Fill up the MENUITEMTEMPLATEHEADER structure.
mheader = (MENUITEMTEMPLATEHEADER*) milist;
mheader->versionNumber = 0;
mheader->offset = 0;
bytes_used = sizeof(MENUITEMTEMPLATEHEADER);
// Add the following menu items to menu bar:
// File Edit
// Exit Copy
// Paste
bytes_used += AddMenuItem(milist + bytes_used, L"&File", 0, TRUE, FALSE);
bytes_used += AddMenuItem(milist + bytes_used, L"E&xit", ID_APP_EXIT, FALSE, TRUE);
bytes_used += AddMenuItem(milist + bytes_used, L"&Background", 1, FALSE, FALSE);
bytes_used += AddMenuItem(milist + bytes_used, L"&Edit", 0, TRUE, TRUE);
bytes_used += AddMenuItem(milist + bytes_used, L"&Copy", ID_EDIT_COPY, FALSE, FALSE);
bytes_used += AddMenuItem(milist + bytes_used, L"&Paste", ID_EDIT_PASTE, FALSE, TRUE);
// Load resource from a menu template in memory.
hMenu = LoadMenuIndirect(milist);
return hMenu;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenu;
POINT point;
switch (message) {
case WM_CREATE:
hMenu = LoadMenuTemplate();
return 0;
case WM_RBUTTONUP:
point.x = LOWORD(lParam);
point.y = HIWORD(lParam);
ClientToScreen(hwnd, &point);
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
# PopMenu.mak
# Use this file as "nmake /f PopMenu.mak" in Visual Studio Command Prompt
CC = cl
LINK = link
CFLAGS = /O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /EHsc /MD /W3 /nologo /c
LDFLAGS = /INCREMENTAL:NO /NOLOGO /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /LTCG /DYNAMICBASE /NXCOMPAT
SYSTEM_LIB = kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
.c.obj:
$(CC) $(CFLAGS) $<
all: PopMenu.exe
PopMenu.exe: PopMenu.obj
$(LINK) /OUT:$@ $(LDFLAGS) $(SYSTEM_LIB) PopMenu.obj
clean:
del *.exe *.obj *.manifest
|
|
|
|
|
Next time, please put your code between <pre> and </pre> tags to make it more readable, if you post this much code this way people won't really feel like reading it thorough.
Anyways, i think what you need to do is to gain the handle of the first popup submenu from the menu you loaded and feed that to TrackPopupMenuEx instead of giving it the menu itself.
So instead of this:
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
try this:
HMENU hPopupThis = GetSubMenu(hMenu, 0);
TrackPopupMenu(hPopupThis, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Hi Code-o-mat,
Thanks for your reply. I've tried your solution, but do not get the popup menu that I expect.
Take my code for example, the popup menu I want is
File -> Exit
Background ->
Edit -> Copy
Paste
Using your solution, only
Exit
is shown.
If I replace the line
HMENU hPopupThis = GetSubMenu(hMenu, 0);
with
HMENU hPopupThis = GetSubMenu(hMenu, 2);
Only
Copy
Paste
is shown.
Given this behavior, I'll try if it works if I compile my menu template like this:
DumbHead -> File -> Exit
Background ->
Edit -> Copy
Paste
|
|
|
|
|
What Code-o-mat is trying to tell you is that you cannot give a handle to a menu to TrackPopupMenu .
You have to give it a handle to a popup menu.
Try this -
Use CreateMenu[^] and InsertMenu[^] to create a menu.
Now you will get the exact same behavior that you see when using TrackPopupMenu .
Change CreateMenu to CreatePopupMenu[^] and everything works well.
|
|
|
|
|
Hello
I'm learning pointers and i have few questions.
In this example i create 1 int variable and 2 char variables
#include <iostream><br />
using namespace std;<br />
<br />
int main ()<br />
{<br />
int b=10;<br />
int *d;<br />
char a='B',c='D';<br />
char *p;<br />
<br />
<br />
cout <<"address of int variable b: "<<&b<<endl;<br />
cout <<"address of char variable a: "<<&a<<endl;<br />
cout <<"address of char variable c: "<<&c<<endl;<br />
p=&c;<br />
cout <<"address of int variable painted by pointer p: "<<p<<endl;<br />
d=&b;<br />
cout <<"address of char variable painted by pointer d: "<<d<<endl;<br />
return 0;<br />
}
I get this result:
address of int variable b: 0x22ff44
address of char variable a: B♀═@
address of char variable c: DB♀═@
address of int variable painted by pointer p: DB♀═@
address of char variable painted by pointer d: 0x22ff44
int type variable address is 0x22ff44. Why do get address symbols B♀═@ with char variables? and if i'm wright cout <<&a and cout << &c stops displaying symbols when reaches end line symbol '\n' ?
This is because char variable is 1 byte long and int 4 bytes ?
Right now I'm bit unfamiliar with memory management in c++.
modified on Sunday, October 18, 2009 1:37 PM
|
|
|
|
|
Tadysas wrote: Why do get address symbols B♀═@ with char variables?
Because cout handles int* differently than char*. A char* is considered to be a string, so cout will output the content of the string. Since you do not have a terminating 0 in your 'string', cout will output some garbage after the first character.
Tadysas wrote: and if i'm wright cout <<&a and cout << &c stops displaying symbols when reaches end line symbol '\n' ?
It stops when it encounter a '\0' character which terminates the string.
Tadysas wrote: This is because char variable is 1 byte long and int 4 bytes ?
No, this is because cout handles pointers to character differently than pointers to integer.
|
|
|
|
|
if you pass a "pointer to char" to cout, you'll get what starts there in memory until a 0x0 is encounterd (it it is the way null-terminated strings are printed out.
Use this instead: cout <<"address of char variable a: "<<(void *) (&a)<<endl;
SkyWalker
|
|
|
|
|
Everybody thanks for help
|
|
|
|
|
I have been using some tree data structure to store data. I met a problem in deleting the space allocated by new manually.If I do not take care of the release of allocated space, the program works well.
I test the code in a win32 console app, the code goes as follow:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int x;
Node*next;
};
void erase(Node*head)
{
if(head->next)
erase(head->next);
delete head;
}
void main( void )
{
Node*a=new Node[2];
a->x=5;
a->next=a+1;
(a+1)->next=0;
erase(a);
// printf( "success!\n");
}
if I comment out erase(a);,the program works fine. OTHERWISE, dbgheap1044 abort!
HOwever, function erase seems good.
I am confused.
|
|
|
|
|
It's because you try to delete a[1], which hasn't been allocated using new. This happens in erase - erase(a) will call erase(a->next). As a->next is a[1], this is equivalent to erase(a[1]).
In addition, you would need to delete a with the array deleter, but it will be deleted in erase, with the scalar deleter.
Try changing the code in main to:
Node*a=new Node;
a->x=5;
a->next=new Node;
a->next->next=0;
erase(a);
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Thank you very much for reply. But, why when erase is commented out, the code section above still works out?
|
|
|
|
|
jianzhuhuai wrote: But, why when erase is commented out, the code section above still works out?
Because without 'erase', you never delete the space you allocated, and C++ really doesn't care if you allocate space without deallocating it! Your users, on the other hand, might well care about the resultant memory leak if it builds and builds so they run out of spare RAM...
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
|
#include <iostream.h>
struct node
{
int info;
node *link;
};
void main()
{
node *p;
int s;
node *create_list();
void print_list(node *);
int sum_of_even(node *);
p=create_list();
print_list(p);
s=sum_of_even(p);
cout<<"The sum of nodes with even values is: "<<s<<endl;
}
node *create_list()
{
node *p, *q=NULL;
int x;
cout<<"Enter the elements of the list (enter \"-1\" without quotes for end)"<<endl;
cin>>x;
while(x!=-1)
{
p=new node;
p->link=q;
p->info=x;
q=p;
cin>>x;
}
return(p);
}
void print_list(node *p)
{
cout<<"The list is: ";
while(p!=NULL)
{
cout<<"->"<<p->info;
p=p->link;
}
cout<<endl;
}
int sum_of_even(node *p)
{
node *q, *q1;
int sum=0;
q=p->link;
q1=q->link;
while(p!=q)
{
if(q->info%2==0)
{
sum+=q->info;
}
q=q->link;
q1=q1->link;
}
return (sum);
}
Without the last function - "int sum_of_even (node *p)" the program worked OK, but after writing it, when the program reaches to that part it crashes. I think that the error is located in the part where I commented, because I can't do the movement to the next node. If anyone knows it would be a big help to me. Thanks in advance.
|
|
|
|
|
Are you sure this is a circular linked list?
It looks like a single link list to me.
And put the following 3 lines outside main()
node *create_list();
void print_list(node *);
int sum_of_even(node *);
|
|
|
|
|
Well, I think that the creation and printing is the same for each list, but the other functions (i.e. adding or deleting a node have slight differences for each kind of a list)
And I thought it was about that, about adding them before main, but it's the same, create list and print list functions work in both ways, but the last one doesn't work on either way, I have mistake in the transition from node to node . Anyway thanks for your reply.
|
|
|
|
|
Naumf wrote: node *create_list();
void print_list(node *);
int sum_of_even(node *);
Move main() below all the other functions and these prototypes can be removed.
Naumf wrote: while(x!=-1)
{
p=new node;
p->link=q;
p->info=x;
q=p;
cin>>x;
}
This while() loop is odd. How about:
while (x > 0)
{
...
x--;
} Since print_list() goes through the list okay, why not model sum_of_even() after it?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
It is the same for the prototypes, It is important to declare them before you use them, and my first two functions work OK, but I have a problem with the code in the last one sum_of_even(). And about the while loop, I use both of them, but I've included this one now. Any help about the last function? BTW thanks for your reply.
|
|
|
|
|
Naumf wrote: It is the same for the prototypes, It is important to declare them before you use them,
Yes, but only if they are located elsewhere. In your case, they are definitely not needed. Just move main() to the bottom.
Naumf wrote: ...but I have a problem with the code in the last one sum_of_even().
And my suggestion corrects that.
Naumf wrote: And about the while loop, I use both of them, but I've included this one now.
But the one I referenced was not right.
Naumf wrote: Any help about the last function?
Other than what I already suggested?
If you will implement my suggestions, your code will work.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
The code you've referenced wasn't right because it needed additional coding...
And about the error, I found it, it was in q1 which wasn't needed at all. And about the declaration it is better to be before main() and it is correctly to be like you say, but it work in both ways . Thanks for your effort.
|
|
|
|
|
Naumf wrote: And about the error, I found it, it was in q1 which wasn't needed at all.
Neither was q .
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
DavidCrow wrote: Neither was q.
I always thought that it's better to work only with p, because in some lists, i.e. singular linked list you don't count that value in the condition, but I don't know the correct coding for that, and this is the way like we are studying stupid but kinda useful xD
|
|
|
|
|
Hello people!
I know, nowadays noone is using DirectDraw anymore but i hope some of you still remember those times and can answer me a question. You can use the flag DDSCL_MULTITHREADED to make DD "multithread-aware". I supose this means that it enables the usage of critical sections or mutexes to add some synching. Now, my question is, is is possible to get access to this mutex or critical section to lock and release it manually?
Thanks in advance for any answers.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Hello, I hope that somebody can help me, the thing is this:
the context: my application has one main dialog and one non-main dialog.
the question: When I press a specific button in the non-main dialog, a line has to be drawn in the client area of the main dialog. how can I do this?
Actually I have a method declared as public and defined in the main dialog class (an instance from Cdialog let's say) to draw my lines, this is the method:
void CCalibracionDlg::BorrarRecta(int Rx,unsigned char D_Ry, unsigned char Vref)
{
CClientDC pDC(this) ;
float tgAng=0,Ry=0;
int x = 0 , y = 0 ,y_=0;
char multiplo=0;
unsigned char indice_recta=0, y_RectaVieja[300];
unsigned int pixel=0, PixelRectaVieja[300];
pDC.SetWindowOrg(-168,-165);
.
.a lot of code that it isn't important for this issue
.
}
Of course when i use this code within the main dialog it works fine, the lines are drawn in the client area of the main dialog, but how can i do to use this code to draw in the client area of the main dialog when i press a button in the non-man dialog? .
Thanks in advance, let me know if you need more information.
|
|
|
|
|