How do I replace MFC CDailog::OnTimer with ATL CAxDialogImpl method? - timer

I had wrote a CMyDailog with MFC based on CDialog. And there is a OnTimer method override the CDialog one.
CMyDailog : public CDialog
{
afx_msg void OnTimer(UINT_PTR nIDEvent)
}
Now, we are migrating our MFC code to ATL. I have to make CMyDailog inherited from CAxDialogImpl<CMyDailog>.
CMyDailog : public CAxDialogImpl<CMyDailog>
{}
I didn't find an equivalent of CDialog::OnTimer in the ATL side. Do I have to use the Windows API ::SetTimer(GolbalTimerFunction) to achive that? In that case, I have to move my original member variable values into the globe scope -- I don't like that.
I find this maybe help:
https://www.codeproject.com/Messages/2870588/what-is-the-event-i-should-use.aspx

I found the equivalent one.
LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
For more detail

Related

calling winAPI functions in vb.net [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have to "translate" / up-date a program that was written in C about 20 years ago to VB.net due to its old SQL connection style that isn't compatible anymore. However, I have minimal experience with C and even less with the winAPI(which the C application uses)... I was wondering, can the same functions from the API be use in VB.net?
I have been able to add a declaration like this:
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Shared Function SetWindowText(hWnd As IntPtr, lpString As String) As Boolean
End Function
to get a window Handle as IntPtr ( in vb.net). However the C program uses functions such as:
BOOL NEAR GoModal( HINSTANCE hInstance, LPCSTR lpszTemplate,HWND hWnd, DLGPROC lpDlgProc, LPARAM lParam )
By importing the user32.dll I can't get the hWnd handle but I can get the IntPtr ( If I understood well, is a point to a window as an integer right? Kinda similar to hWnd --> I could be TOTALLY wrong, but this is what I understood)
As I go to the definition of each type (i.e: NEAR , HINSTANCE, LPCSTR, etc...) I try to find an equivalent call in VB but ... its useless. For instance, I was looking at NEAR and I guess it was to decide if two pointers were close in memory ? ( again might be wrong, it's just what I gathered).
Ultimately, my question is, would such call exist in vb.net / even be useful with the more modern framework and such?
Let's break down the parameters in the function call:
BOOL NEAR GoModal(HINSTANCE hInstance,
LPCSTR lpszTemplate,
HWND hWnd,
DLGPROC lpDlgProc,
LPARAM lParam )
BOOL is a 32 bit integer. You can use the System.Boolean type in your code, but it needs the MarshalAsAttribute applied to it, specifying the type as UnmanagedType.Bool
NEAR specifies information to the compiler. When translating to .net, you can ignore it.
HINSTANCE is a Handle to an Instance. Translating to .net, handles are typically defined as IntPtr values. This doesn't mean that it's a pointer to memory. (ie- Marshal.Read can't be used.)
LPCSTR is a Long Pointer to a C style STRing. This is an ANSI string, so it means that the parameter needs the MarshalAsAttribute with UnmanagedType.LPStr. If this is was an out parameter, things would be more complicated, and you'd either need to pass a StringBuilder or use Marshal.AllocHGlobal/Marshal.AllocCoTaskMem to get unmanaged memory allocated.
HWND is a Handle to a Window. Like the HINSTANCE it is typically marshalled as an IntPtr
DLGPROC is a bit more complex, so I'll address it below.
LPARAM is a Long Parameter. The standard implementation that Microsoft used for this type when they created the Message class, is IntPtr. You should follow suit.
As I said above DLGPROC is more complex. It is actually a pointer (reference) to a function. Specifically one with the signature:
INT_PTR CALLBACK DialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
We've already seen HWND and LPARAM, so let's take a quick look at the other things in this signature.
INT_PTR is an Integer Pointer. If that sounds familiar, it should. It's just an IntPtr.
CALLBACK is another bit of information that the compiler uses to determine how the function should be compiled, and how people using it should send their parameters to the function. By default the .net marshal handles this, so no additional configuration is needed.
WPARAM stands for Word Param. In this case, it's old terminology, and you will want to use IntPtr to receive the value.
To marshal a pointer to a DLGPROC, you will need to create a delegate with the appropriate signature:
Delegate Function DLGPROC(ByVal hWnd As IntPtr,
ByVal uMsg As UInt32,
ByVal wParam As IntPtr,
ByVal lParam As IntPtr) As IntPtr
You then need to create a function somewhere in your code, with the same signature, to receive the call from the native code. Something like:
Private Function MyDialogProc(ByVal hWnd As IntPtr,
ByVal uMsg As UInt32,
ByVal wParam As IntPtr,
ByVal lParam As IntPtr) As IntPtr
Return IntPtr.Zero ' Put the appropriate code here.
End Function
You then can add a class member to hold that delegate:
Private DialogProc As DLGPROC = New DLGPROC(AddressOf Me.MyDialogProc)
After all of that, you're finally ready to import the GoModal function prototype. (YAY!) That looks like:
<DllImport("DLL_NAME")>
Private Shared Function GoModal(ByVal hInstance As IntPtr,
<MarshalAs(UnmanagedType.LPStr)> ByVal lpszTemplate As String,
ByVal hWnd As IntPtr,
ByVal lpDlgProc As IntPtr, ' More on this below
ByVal lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
We can now call the function from our code:
Dim dialogProcedure As IntPtr = Marshal.GetFunctionPointerForDelegate(Me.DialogProc)
Dim result As Boolean = GoModal(IntPtr.Zero,
"Template",
Me.Handle,
dialogProcedure,
New IntPtr(100))
Two notes about the function call:
IntPtr.Zero is the same as NULL
New IntPtr(100) creates an IntPtr with the specified value. (Sometimes the LPARAM is just a number)
And if you made it this far, Congratulations! There may be a couple bugs in the code, but this should get you going. For other Windows API types, you can find a lot of information at pinvoke.net.
If you have a lot of interop to do, it would be easier to just add a C++/CLI dll to your project and call these functions natively. It's much, much easier, and you can define the functions exactly how you want them. In addition, C++/CLI works with any of the .net languages.

Why use Func<> in controller constructor parameters in MVVM applications

I'm seeing, more and more code like the code below in an MVVM application (WPF and Prism). Controllers have the following code fragments:
public class DispenseOptionController : IDispenseOptionController
{
protected readonly Func<IPharmacyCdmServiceSimpleClient> CdmClient;
protected readonly Func<IPatientServiceSimpleClient> PatientClient;
public DispenseOptionController(Func<IPharmacyCdmServiceSimpleClient> cdmClient, Func<IPatientServiceSimpleClient> patientClient)
{
CdmClient = cdmClient;
PatientClient = patientClient;
}...
I'm trying to understand the role that Func<> plays here. It seems that this delegate is used as parameters to the constructor. Can someone explain to me why anyone would use Func<> in this particular case? And can Func<> be replaced with anything else?
A Func<> is nothing but the Encapsulation of a method that one or more parameter and returns a value of the type specified by the TResult parameter.
You could see some use cases here

How to use parameterless constructor with ninject di and winforms

I'm working on a WinForm application using ninject for dependency injection. My first problem was that the form being instantiated had a parameter (for DI). I added a parameterless constructor thinking this would help. The problem now is that the code inside the constructor with the parameter gets skipped. Here what it looks like:
On my main form:
private void mnuSettings_Click(object sender, System.EventArgs e)
{
frmSettings objForm = new frmSettings();
objForm.Owner=this;
objForm.Show();
}
In the frmSettings form:
private readonly IApplicationPropertiesInterface _applicationProperties;
public frmSettings()
{
InitializeComponent();
}
public frmSettings(IApplicationPropertiesInterface applicationProperties) : this()
{
_applicationProperties = applicationProperties;
}
When I call _applicationProperties.GetExtractFileSaveLocationDirectory() it blows up because the code to set _applicationProperties was never called.
Im wondering if I have structured this incorrectly, and what the best way to achieve this is. My goal is to call the parameterless constructor, but also set _applicationProperties.
Any assistance would be most grateful.
I'm guessing you might be expecting that having Ninject in the building will mena that new will work differently to normal. It doesn't - you need to be doing a kernel.Resolve<Something> for the DI to kick in. Note that most of these pitfalls are covered in detail on the wiki
Can you edit your answer to include details of what you're doing outside of this form please?
In the meantime, here are some previous questions that overlap significantly:-
What is the best practice for WinForms dialogs with ninject?
How to use Ninject in a Windows Forms application?

Visual Studio .NET error: Form does not contain Dispose(bool) method

Occasionally Visual Studio (2005, 2008, 2010) will lose its mind, and get confused by a WinForm:
SplashForm.cs:
public partial class SplashForm : Form
{
...
SplashForm.Designer.cs:
partial class SplashForm
{
...
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
...
It will complain:
protected override void Dispose(bool disposing)
'Dispose(bool)' has no suitable method to override
base.Dispose(disposing);
'object' does not contain a definition for 'Dispose`
It's complaining about code that it generated.
It's been too long (3 years) since i dealt with Visual Studio, so i've forgotten the trick to get Visual Studio's head out of its own assembly.
What's the trick to get it going again?
I had this issue today and found this question. I managed to fix it and while the post is old (2 years old now) I think it is always good to answer it with the solution I found:
My Scenario: I created a form in the wrong directory
The result: The namespace was different from the namespaces of the other forms.
The cause: In my specific case, this was caused because I changed the <Form>.Designer.cs namespace so that it matched the rest of the forms Namespace. But I didn't change the <Form>.cs namespace and that was my mistake.
So, if you're having this error, make sure both your namespaces from the <Form>.Designer.cs and <Form>.cs match.
Well i fixed it.
i excluded:
SplashForm.cs
SplashForm.Designer.cs
SplashForm.resx
from the project, and moved the files to another folder.
Then i created a new form, called SplashForm, and copied the contents of:
SplashForm.cs
SplashForm.Designer.cs
SplashForm.resx
from the backup copies.

Getting windows caption from process ID

I have a process ID, what I want to do is return the class. If it is the desired class then return the caption, how do I do that?
C Visual Studio 2008, XP SP3
Use EnumWindows with GetWindowThreadProcessID to find the HWND with the matching process ID that you're looking for.
Once you have the HWND you can use GetClassName to get the class name.
Once you have the HWND with the class you want you can use either:
SendMessage to send a WM_GETTEXT.
Or GetWindowText
Read Raymond Chen's post here on the differences.

Resources