GetDlgItem, works in one class and not in another - windows

I am trying to use the function GetDlgItem(int id) and not the GetDlgItem(HWND par, int id). In other parts my code I use GetDlgItem as such
CWnd * pWnd;
pWnd = GetDlgItem(IDC_UPPER_BTN);
And it works fine. But in another class I am trying to do the exact same thing and it keeps demanding a HWND.
When I search GetDlgItem I see there is a MFC and a windows version. How can I specify which one I want to use?

You can specify the member function explicitly using:
this->GetDlgItem(...);
You can specify the global function explicitly using:
::GetDlgItem(...);

Related

get unique ID for Win32 DLL instance?

Is there a simple way to get a unique ID for the specific DLL instance some C/C++ code is currently running in? Maybe &DllMain? But that function is optional.
I'm writing a plugin dll that registers a window class name, but I need a different window class name for each plugin instance
No, you don't. DLLs don't have unique IDs, but they do have unique HINSTANCEs. Multiple DLLs can register the same class name, but still do different things. The classes are differentiated by the HINSTANCE that registers/creates them at runtime.
Refer to this for more info:
What is the HINSTANCE passed to CreateWindow and RegisterClass used for?
When it comes time to create a window, each module then passes its own HINSTANCE when creating the window, and the window manager uses the combination of the instance handle and the class name to look up the class.
CreateWindow("MyClass", ..., hinstA, ...); // creates class 6
CreateWindow("MyClass", ..., hinstB, ...); // creates class 7
CreateWindow("MyClass", ..., hinstC, ...); // fails
This is why it is okay if multiple DLLs all register a class called “MyClass”; the instance handle is used to tell them apart.

Calling FindWindowEx with program WIndowClass

I'm trying to use FindWindowEx to determine whether a certain program is running or not.
FindWindow(NULL, "Mozilla Firefox");
This works fine as long as I'm on firefox's start page. A workaround I found was:
FindWindow(NULL, "MozillaWindowClass");
But that left me wondering if that was specifically crafted for firefox, but it turns that it appeareantly works for other applications:
FindWindow(NULL, "OllyDbgWindowClass");
So my question is can I just use FindWindow with an argument like "programXWindowClass" for any program? Are there any exceptions to this?
Is "programXWindowClass" guaranteed to exist?
There is no requirement for a caller to RegisterClassEx to follow any particular pattern, that maps a window class name to any other information (like the application name). Any caller can pick any valid window class name they like.
Keep in mind two notable consequences of this:
A window class name need not be unique to any given application. All UWP applications use the window class "Windows.UI.Core.CoreWindow" by default, for example.
A window class name can change across different versions of an application, or even different invocations of an application.
Is "programXWindowClass" guaranteed to exist?
No. What you observed is merely a coincidence in naming.

Why must I use UserControl.MousePointer instead of Me.MousePointer?

In VB6 on a UserControl, I must use UserControl.MousePointer = vbDefault instead of Me.MousePointer = vbDefault. I can use Me.MousePointer on a Form (and Form.MousePointer doesn't work).
Why must I use UserControl.MousePointer instead of Me.MousePointer?
I mean literally the text "UserControl", not UserControl as the placeholder for another control name.
Me isn't what you seem to think it is. It is a reference to the current instance of the module you use it in, not "magic."
To get what you want you must add this property to the default interface of your UserControl, e.g.:
Option Explicit
Public Property Get MousePointer() As MousePointerConstants
MousePointer = UserControl.MousePointer
End Property
Public Sub Test()
MsgBox Me.MousePointer
End Sub
In VB6 Forms are a little different, probably as a holdover from 16-bit VB to make porting old code easier. These always seem to inherit from a hidden interface. This is defined in a type library you don't have access to since Microsoft did not release it as part of VB6. Attempting to query it typically comes up with an error like:
Cannot jump to 'MousePointer' because it is in the library 'Unknown10' which is not currently referenced
From this alone it seems likely that using Me always carries a small performance penalty. Instead of going directly to the module's procedures it appears to me that you are going through its default COM interface.
You'd have to inspect the compiled code to determine whether there is a performance penalty, and if so how much. I don't see this documented so otherwise we are just guessing about it.
In any case there is little reason to ever use Me unless you must in order to qualify something.
Crummy example but:
Option Explicit
Private mCharm As Long
Public Property Get Charm() As Long
Charm = mCharm
End Property
Public Property Let Charm(ByVal RHS As Long)
mCharm = RHS
'Maybe we do more here such as update the user interface or some
'other things.
End Property
Public Sub GetLucky(ByVal Charm As Long)
'Do some stuff.
Charm = Charm + Int(Rnd() * 50000)
'etc.
Me.Charm = Charm 'Here we use Me so we can assign to the property Charm.
End Sub
That's really about the only legitimate use for Me anyway: scoping to the desired namespace. Relying on it because in typing it brings up IntelliSense is just lazy.
If anything Forms are "broken" not UserControls.
Figured it out. It turns out that since a UserControl is an ActiveX control, VB6 does some magic for you. With a Form control, it's not an ActiveX control which is why the MousePointer property is accessible via Me, like you'd expect.
For UserControl's, the UserControl control you create in VB6 sits on another control - the ActiveX control. That ActiveX control is accessible via UserControl. Something like this:
class ActiveXControl
{
int MousePointer;
VBUserControl control;
}
class VBUserControl
{
}
class YourUserControl : VBUserControl
{
ActiveXControl UserControl;
// we must use UserControl.MousePointer
}
but for a Form, it's more like this:
class Form
{
int MousePointer;
}
class YourForm : Form
{
// we actually inherit from Form so we use Me.MousePointer
}

Is there any way to make the DialogProc work without declaring as Nonstatic

I have developed any button application using createDialogParam and DialogProc. first i declared DialoProc method as static in order to make every thing work fine and it worked but now the situation is that there are so many variables(Not globally declared) and functions which i have to use inside DialogProc function and now i want to make it Non static because making it static makes me not implement few more things.
If i don't declare it static it gives error
m_hwndPreview = CreateDialogParam( g_hInst,MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent,(DLGPROC)DialogProc, (LPARAM)this); //('type cast' cannot convert from 'overloaded-function'
//to 'DLGPROC')
Is there any solution to make dialogProc function without declaring it static ???
It must be a static function because Windows calls it from C code, not C++ code. But there are several ways your static function can retrieve a 'this' pointer that you saved somewhere, then use that pointer to call a class member function. Every GUI library available for Windows solves this problem: Consider using one.

Break out of ATL class into Win32 functions

I'm trying to call the Win32 version of SetWindowPos from within an ATL class (I need to specify a different first hWnd, which ATL normally handles), but I can't 'break out' of the ATL class and get the following error:
error C2661: 'ATL::CWindow::SetWindowPos' : no overloaded function
takes 7 arguments
How do I tell it I don't want to use the one in my base class?!
Dumbass answer... suppose someone else might have the same problem.
Prefix :: to access the global namespace. (Courtesy of CodeGuru).

Resources