What's new

Two questions

Doomulation

?????????????????????????
I'm not very good at GUI programming, really... and what's worse is that advanced functions are almost never incapsuled into the MFC classes... damn you ms!

Anyway, what I want to know is how to change the behaviour of a drop-down list. It uses the styles CBS_SIMPLE, CBS_DROPDOWNLIST or CBS_LIST I think or whatever... but the question is, how do I apply to change this behaviour? Sometimes I want the combobox simply to be a textbox, and at other times only a drop-down list. SetWindowLong didn't work for me. I tried to set these styles for it, but it didn't change! Don't get why...

Also... has anyone noticed that if you use a richtext box, the form you use it on won't display. It doesn't matter if it's MFC or not. I tracked down the problem to CreateDialogIndirect. Also affects any other of these functions that creates dialogs from templates. Oddly enough, they return a NULL pointer indicating a failiure, and yet when you call GetLastError() it returns 0 (success). That must be big miss by ms. Ooooohhh... that has GOT to hurt! I can't see how they missed that? Something is definetly wrong, and my guess is that it's in their API.

Now would anyone PLEASE answer the question above? :p Haha, thanks if you do. :happy:
 

aprentice

Moderator
I don't know if this is what you are looking for, but I'll just post it here anyway, its a clip from an irc client i was working on in the past, if its helpful, let me know.

//Create Rich Edit Box for Chat
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "RICHEDIT", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 100, 100, hwnd, (HMENU)IDC_CHILD_EDIT, GetModuleHandle(NULL), NULL);

if(hEdit == NULL) MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);

SetWindowText(hEdit,"");
SetWindowPos(hEdit,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
 

smcd

Active member
To use a richedit control you need to load the RichEd32.dll, if it's MFC put this in the InitInstance function:
Code:
AfxInitRichEdit();
if you're doing API, call
Code:
LoadLibrary("RichEd32.dll"); /* riched20.dll i think could work too */
either way you need to somehow get it in your process space.

As far as the SetWindowLong stuff, I've had mixed results when using that. www.winprog.org has a FAQ section with a function to update the styles of a window, might want to look at that example.
http://www.winprog.org/faq/#part.api.windows.modify-style
 
OP
Doomulation

Doomulation

?????????????????????????
Hmm yes, interesting site! I will try it out.
Funny though how microsoft seemingly have "missed" to induldge me the information I need to include such statements to use the richtext controls...
Oh well. At least I got the info. That's very nice... yes, that's very nice... I'll try it out... both of them! Thanks!
 
OP
Doomulation

Doomulation

?????????????????????????
Another question I have...
Why is it that increasing pointer addresses have a bad effect? Take a look at this:

pInfo += 0x14;

Seems reasonable, doesn't it? Yet, this is the asm code produced:

1001589E mov eax,dword ptr [pInfo]
100158A1 add eax,0FF0h
100158A6 mov dword ptr [pInfo],eax

Why, is my question! Why does this happen? I mean 0xFF? WTF?
I tried my own asm therefore, with excellent results:

__asm
{
mov eax, pInfo;
add eax, 0x14;
mov pInfo, eax;
}

This strikes me odd, as to why it does that.
 

Orkin

d1R3c764 & g1|\|64 m4|<3R
Doomulation said:
Another question I have...
Why, is my question! Why does this happen? I mean 0xFF? WTF?

The reason it does that is because it thinks in terms of how many indices you're adding to the pointer address, not how many bytes...not sure that's clear, here's an example:

Code:
struct Address
{
    CString street, city, state, zip;
};

Address *addressPtr;

addressPtr = [i]someAddressPointer[/i]

// Move the pointer to the next address
addressPtr += 1; // The compiler actually adds sizeof( Address ) to the pointer

// Move the pointer two addresses
addressPtr += 2; // The compiler actually adds sizeof( Address ) * 2

Hope this clears things up...
 

smcd

Active member
Yup, what orkin said. What type is pInfo pointing to? (how large) Take this size * 0x14 and you should see where the FF0h comes from.
 
OP
Doomulation

Doomulation

?????????????????????????
Tricky... I don't see much use for that. What would be a good use for this?
That pInfo pointer poined to a struct with two shorts I believe. I changed it frequently while testing something so I can't be 100% sure.

EDIT:
Three more things:
I just wondered... when I previously creatred a modeless window, I encountered something strange... I did it with MFC of course. Watch this:

Code:
CMyDialog* dlg; // Global

if (dlg == NULL)
{
dlg->Create();
dlg->ShowWindow(SW_SHOW);
dlg->SetOwner(this);
}

When I call SetOwner, the window tend to freeze; and with it the main window as well. I can't see why SetOwner would do this? I tried SetOwner because if I created the window with the main win as the parent, it would stay on top of it for some weird reason. Also note that dlg->DoModal(); works fine in any case. Is there some deadlock here?

Question two:
How do you type cast something without asigning it to a variable? Let me demonstrate. Take the previous example... I want the window to call a member function in the main window (the parent). GetOwner() of course returns CWnd*. So, I have to type cast it to use the functions of the main win.

This is how I want it:
Code:
GetOwner()->SomeMemberFunc();

This is how I do it atm:
Code:
CMyMainDlg* pDlg = (CMyMainDlg*)GetOwner();
pDlg->SomeMemberFunc();

I know I've seen somewhere that it can be done... but I can't remember how to do it.

Three:
I've been pondering about the map class handed down in the C++ libraries, in the std namespace. It seems quite inflexible by that if you take a char* as the key, you will sometimes be unable to aquire the element pointed to by this key. Like so:

Code:
map<char*,int> MyMap;
void func1(char* map)
{
MyMap[map] = 10;
}

void func2(char* map)
{
int ret = MyMap[map];
}

Chances are, in function two, it will return 0, and not 10. Perhaps it's storing the address itself as the key? I don't know. All I know is that if you use a string class such as std::string or CString, it works fine. A char array doesn't work.

Code:
map <char[100],int> MyMap

...gives an error. Must you use classes such as this to map a string to elements with this class? Just wondering if anyone knew something...
 
Last edited:

Cyberman

Moderator
Moderator
Doomulation said:
Tricky... I don't see much use for that. What would be a good use for this?
That pInfo pointer poined to a struct with two shorts I believe. I changed it frequently while testing something so I can't be 100% sure.
No it's not tricky. It's in the C specs. It makes perfect sense as well. Think of a pointer as a pointer to something. For example lets take a structure whose size is 123 bytes. When you increment the pointer it's the same as changing an index to an array by one. In fact in C/C++ this is perfectly valid:
Code:
typedef struct
{
  int somestuff[24];
} somestruct;

somestruct * SomePtr;

SomePtr = new somestruct[100];

for(int Index = 0; Index < 100; Index++)
{
  SomePtr[Index].somestuff[0] = 0;
}
SomePtr is treated as an array if you noticed. That's technically how the language works.
Doomulation said:
EDIT:
Three more things:
I just wondered... when I previously creatred a modeless window, I encountered something strange... I did it with MFC of course. Watch this:

Code:
CMyDialog* dlg; // Global

if (dlg == NULL)
{
dlg->Create();
dlg->ShowWindow(SW_SHOW);
dlg->SetOwner(this);
}

When I call SetOwner, the window tend to freeze; and with it the main window as well. I can't see why SetOwner would do this? I tried SetOwner because if I created the window with the main win as the parent, it would stay on top of it for some weird reason. Also note that dlg->DoModal(); works fine in any case. Is there some deadlock here?
Owner needs to be of type HWINDOWINSTANCE no? Are you passing a pointer to your object? This will create a problem perhaps passing a pointer/reference to a window that's the owner will help? THIS referes to your current object which is damn unlikely to be a legal window refence! ;) Also it's a BAD idea to pass the current object as an owner of a window. True passing the OWNER of the current object instead. I bet it will work right. (that's what I do in any case).
Doomulation said:
Question two:
How do you type cast something without asigning it to a variable? Let me demonstrate. Take the previous example... I want the window to call a member function in the main window (the parent). GetOwner() of course returns CWnd*. So, I have to type cast it to use the functions of the main win.

This is how I want it:
Code:
GetOwner()->SomeMemberFunc();

This is how I do it atm:
Code:
CMyMainDlg* pDlg = (CMyMainDlg*)GetOwner();
pDlg->SomeMemberFunc();

I know I've seen somewhere that it can be done... but I can't remember how to do it.
Code:
((SOMEWINDOWTYPE *)GetOwner())->SomeMemberFunc();
how about that? :)
 
Last edited:
OP
Doomulation

Doomulation

?????????????????????????
Cyberman said:
No it's not tricky. It's in the C specs. It makes perfect sense as well. Think of a pointer as a pointer to something. For example lets take a structure whose size is 123 bytes. When you increment the pointer it's the same as changing an index to an array by one. In fact in C/C++ this is perfectly valid:
Code:
typedef struct
{
  int somestuff[24];
} somestruct;

somestruct * SomePtr;

SomePtr = new somestruct[100];

for(int Index = 0; Index < 100; Index++)
{
  SomePtr[Index].somestuff[0] = 0;
}
SomePtr is treated as an array if you noticed. That's technically how the language works.
Of course it's tricky :p Doesn't matter if it's in the specs or not, you're not used to that. Okay, I do admit that I don't use something like...
Code:
memcpy(ptr+70,bla bla);
On anything besides char* pointers, but whatever... hehe. Of course [index] makes sense. Duh. Heh. Thanks for the heads up.

Owner needs to be of type HWINDOWINSTANCE no? Are you passing a pointer to your object? This will create a problem perhaps passing a pointer/reference to a window that's the owner will help? THIS referes to your current object which is damn unlikely to be a legal window refence! ;) Also it's a BAD idea to pass the current object as an owner of a window. True passing the OWNER of the current object instead. I bet it will work right. (that's what I do in any case).
Okay, don't getcha completely here. I'm creating a new window from my main window and passing the THIS pointer which point to the current class I'm in of course, as the owner. THAT, is what's causing the problem. If I don't pass any parameter (pass NULL), the framework will call AfxGetMainWin() (gets the handle to your main window, the same window I'm trying to pass as owner). Works fine if I specify the main window as the owner when creating the window, but not after. And MFC basically wraps up such api functions, so I guess it should happen with pure win32 as well, though I never tried.

Code:
((SOMEWINDOWTYPE *)GetOwner())->SomeMemberFunc();
how about that? :)
Oh yes, I never thought about that! =)
 

Cyberman

Moderator
Moderator
Doomulation said:
Of course it's tricky :p Doesn't matter if it's in the specs or not, you're not used to that. Okay, I do admit that I don't use something like...
Code:
memcpy(ptr+70,bla bla);
On anything besides char* pointers, but whatever... hehe. Of course [index] makes sense. Duh. Heh. Thanks for the heads up.
Which brings up another possible problem or situation that can come up. You'll notice some objects use an 'assign' function instead of an assignment operator. The reason behind this is the assignment operator can be dangerous if not used properly. Especially with temporary variables being created by C++. This problem stems from the object constructor and destructor being called having dire consequences. Having a function for assignment is safer because the compilor doesn't create a temporary variable of the object type (and thus won't call the constructor and destructor on it). This has bit me hard in the past :)

You should also NOT use memcpy() on objects. If you have data in the objects that's raw, then it's fine but not for copying objects. Always use the C++ asignment operator or the assign function of the object type for that. It's not as 'simple' looking but you are less likely to mess up the object and it's highly compilor dependant how the data is organized.

Doomulation said:
Okay, don't getcha completely here. I'm creating a new window from my main window and passing the THIS pointer which point to the current class I'm in of course, as the owner. THAT, is what's causing the problem. If I don't pass any parameter (pass NULL), the framework will call AfxGetMainWin() (gets the handle to your main window, the same window I'm trying to pass as owner). Works fine if I specify the main window as the owner when creating the window, but not after. And MFC basically wraps up such api functions, so I guess it should happen with pure win32 as well, though I never tried.
You can only assign the owner to a window object once. If you use NULL it uses the applications main window by default. I hope that makes sense to you.
Doomulation said:
Oh yes, I never thought about that! =)
Just my evil past showing up in me sharing easy ways to do things you probably shouldn't be doing ;)

Cyb
 
Last edited:
OP
Doomulation

Doomulation

?????????????????????????
Cyberman said:
Which brings up another possible problem or situation that can come up. You'll notice some objects use an 'assign' function instead of an assignment operator. The reason behind this is the assignment operator can be dangerous if not used properly. Especially with temporary variables being created by C++. This problem stems from the object constructor and destructor being called having dire consequences. Having a function for assignment is safer because the compilor doesn't create a temporary variable of the object type (and thus won't call the constructor and destructor on it). This has bit me hard in the past :)
Okay sounds... scary O_O Actually, I've never overloaded the assignment operator up-to-date. Or at least not much. I think I did an experimental class with it once, but it's never evolved.
I can't say for certain if it's good or bad, but if you use pointers or references in the assigment functions and return *this, then no temp objects should be created? I'm not sure, but I would find out if I tried, I guess.

You should also NOT use memcpy() on objects. If you have data in the objects that's raw, then it's fine but not for copying objects. Always use the C++ asignment operator or the assign function of the object type for that. It's not as 'simple' looking but you are less likely to mess up the object and it's highly compilor dependant how the data is organized.
Oh don't worry about that. I've never done that. When I use memcpy, it's structs I use.

You can only assign the owner to a window object once. If you use NULL it uses the applications main window by default. I hope that makes sense to you.
Sounds fishy to me if you include such a function when it musn't be done after creating the window. The docs does not mention such a thing either. Sigh, so much that is left out. Always in the ms docs.

Just my evil past showing up in me sharing easy ways to do things you probably shouldn't be doing ;)

Cyb
=) Works perfecly anyway! Love it!
 

Top