Alternative for ON_COMMAND message map macro to call a function with a paramenter(s) - visual-c++

I've got a message map at the beginning of my program that looks like the following:
BEGIN_MESSAGE_MAP(SoftwareDlg, CDialog)
//{{AFX_MSG_MAP(SoftwareDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_DESTROY()
...
ON_COMMAND(ID_TOOLS_UPLOADDATA, UploadData)
...
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
And here the function that the ID_TOOLS_UPLOADDATA menu option calls when clicked:
void UploadData()
{
string apiEndpoint = "/api/stuff";
upload_data(apiEndpoint);
}
My problem is that that I want my UploadData() function to be able to take the string apiEndpoint as a parameter so that I can call it from multiple locations in my program for multiple operations (not just when the user clicks the menu button). Like so:
void UploadData(string apiEndpoint = "/api/stuff")
{
upload_data(apiEndpoint);
}
I took a look at ON_COMMAND_EX, but the only usage example I was able to find does not appear to be what I'm looking for... Anyone have any ideas?

As #Iinspectable said, you can’t.
Try for example to add a member variable and set it before calling the function.

Related

Haxe 4: Uncaught exception macro-in-macro

I had code like this working with Haxe 3:
macro public static function get(key:String)
{
return Context.makeExpr(Context.definedValue(key), Context.currentPos());
}
However, after migrating to Haxe 4 this fails to compile with error:
Uncaught exception macro-in-macro
How should I go about migrating this function to Haxe 4? Is there a better way to access build flags in order to avoid this issue?
As #Gama11 alluded to, there's not actually a problem with your macro function, there's a problem with where you're calling it from. (Haxe 4 may have gotten more strict with these checks.)
If you have:
Main.hx
class Main
{
public static function main()
{
// Can call get from here:
var cvar = MacroUtil.get('cvar');
MacroUtil.some_macro_function();
trace('Hello world! cvar=${ cvar }');
}
}
MacroUtil.hx
import haxe.macro.Context;
import haxe.macro.Expr;
class MacroUtil
{
macro public static function get(key:String):Expr
{
return Context.makeExpr(Context.definedValue(key), Context.currentPos());
}
macro public static function some_macro_function()
{
// Cannot call get from here:
var cvar:Expr = get('cvar');
trace('will trace at compile time, and cvar is ${ cvar }');
return macro trace('will trace at runtime');
}
}
And execute it with: haxe -x Main -D cvar=abc
That will generate the error you're experiencing. It's because in some_macro_function, you're already in the macro context, so you can't call the macro function get from there.
There are a couple ways of dealing with this.
One Approach
You can use #if macro / if !macro to detect the macro context and adjust accordingly. So as silly as this looks, it does indeed solve your particular problem:
class MacroUtil
{
#if !macro macro #end public static function get(key:String):Expr
{
This function signature says, if I'm already in the macro context, don't consider this function a macro function. It's just a static helper at that point. And remember that it returns an Expr, not a String like it does in the main context.
If you mix macro and non-macro functions in a single file, you may also find yourself needing to use #if macro to avoid this condition as well.
Another Approach
You can refactor your macro functions into macro functions and macro helpers. It's a little more verbose, but maybe a little more clear as to what's happening:
MacroUtil.hx
import haxe.macro.Context;
import haxe.macro.Expr;
class MacroUtil
{
macro public static function get(key:String):Expr
{
return Context.makeExpr(MacroHelpers.get_define(key), Context.currentPos());
}
macro public static function some_macro_function()
{
// Cannot call get from here:
var cvar:String = MacroHelpers.get_define('cvar');
trace('will trace at compile time, and cvar is ${ cvar }');
return macro trace('will trace at runtime');
}
}
class MacroHelpers
{
public static function get_define(key:String):String
{
return Context.definedValue(key);
}
}
If you do it this way, then your macro functions all call the MacroHelpers, and non-macro function call the MacroUtils. Notice the helper returns a String, and it's up to the call-site to then convert it to an expression, if that's what they want.
We ended up removing this whole get method and switching occurrences to use Compiler.getDefine() instead, which is supported both by Haxe 3 and 4.
I believe the problem we were facing was related with the fact that this static macro get was being called from our test runner script, so that probably was the place where a macro was calling another macro. Still, I tried to put the solution suggested by Jeff Ward in place but kept getting the same result.

Geb / Groovy - Page content not recognized when used within other Page Object method

When I click a button I have to wait for some dynamic content to be rendered. When I put the waitFor closure in the test it works correctly. However, I wanted to put the waitFor in a method inside the Page object so I do not have to always call the waitFor after every click, but when I do that it fails stating it cannot find the property.
This does not work:
class LandingPage extends Page {
static content = {
resultsBtn(to: ResultsPage) { $("button", id: "showresults") }
}
void getResults() {
resultsBtn.click()
waitFor { ResultsPage.results.displayed }
}
}
class ResultsPage extends Page {
static content = {
results { $("div", id: "listresults") }
}
}
class ShowResults extends GebReportingTest {
#Test
public void displayResults() {
to LandingPage
getResults()
}
}
The error states something like "No such property: results for class ResultsPage".
Is it possible to put references to content from other Page Objects inside other Page Object methods?
EDIT: I feel like this is more of a Groovy specific thing rather than Geb. I'm not sure if it's even possible to access bindings within the content closure. But it also seems like creating a getVariable() function inside the Page Object doesn't help much either.
First you shouldn't assign closures in content blocks (there's unnecessary = in ResultPage) but pass them to an implicit method, you should have:
static content = {
results { $("div", id: "listresults") }
}
The other question is why do you want to model this as two pages? As far as I understand clicking the button doesn't cause a page reload but there's an ajax call to retrieve the results. I would simply put both results and resultsBtn as contents of one page and your problem would be gone.
EDIT:
It turns out that a page change is involved in your case. Assuming that you always want to wait for these results to appear you can either:
put your waitFor condition inside of static at = {} block for ResultsPage - at checks are executed implicitly whenever you use to() which means that it will wait wherever you go to that page
put a waitFor in a page change listener
access current page via the browser property on a page, in LandingPage: waitFor { browser.page.results.displayed } but this seems like a dirty solution to me - reaching from one page to another...

How to call a function in mfc...?

I am new to MFC PROGRAMMING. I use vs 2008, in a Dialog Based App. I want to call bellow function on a button click event...?
When I call like SortList(listboxone); is giving an error that SortList not found...!
Please help me..!!
void SortList(CListBox& templistbox)
{
DWORD_PTR abc;
int a=templistbox.GetCurSel();// Select current Item Index
if(a<templistbox.GetCount()-1)
{
abc = (DWORD_PTR )templistbox.GetItemData(a);
a++;
templistbox.SetItemData(a,(DWORD_PTR) templistbox.GetItemData(templistbox.GetCurSel()));
}
}
Sorry now I changed the function to as above but still gives same error.
You probably are calling the function above the function definition. In C/C++, you need to define the function (or it's prototype at least) before calling the function. Put this:
void SortList(CListBox& templistbox);
at the the top of the source file.

Get parameter values from method at run time

I have the current method example:
public void MethodName(string param1,int param2)
{
object[] obj = new object[] { (object) param1, (object) param2 };
//Code to that uses this array to invoke dynamic methods
}
Is there a dynamic way (I am guessing using reflection) that will get the current executing method parameter values and place them in a object array? I have read that you can get parameter information using MethodBase and MethodInfo but those only have information about the parameter and not the value it self which is what I need.
So for example if I pass "test" and 1 as method parameters without coding for the specific parameters can I get a object array with two indexes { "test", 1 }?
I would really like to not have to use a third party API, but if it has source code for that API then I will accept that as an answer as long as its not a huge API and there is no simple way to do it without this API.
I am sure there must be a way, maybe using the stack, who knows. You guys are the experts and that is why I come here.
Thank you in advance, I can't wait to see how this is done.
EDIT
It may not be clear so here some extra information. This code example is just that, an example to show what I want. It would be to bloated and big to show the actual code where it is needed but the question is how to get the array without manually creating one. I need to some how get the values and place them in a array without coding the specific parameters.
Using reflection you can extract the parameters name and metadata but not the actual values :
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.testMethod("abcd", 1);
Console.ReadLine();
}
public void testMethod(string a, int b)
{
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
StackFrame sf = st.GetFrame(0);
ParameterInfo[] pis = sf.GetMethod().GetParameters();
foreach (ParameterInfo pi in pis)
{
Console.Out.WriteLine(pi.Name);
}
}
}

MFC - Problems with CFrameWnd::LoadFrame() in "hello world"

So, here's my code (for simplicity I put it all into one file):
#include <afxwin.h>
#include "resource.h"
class CMainWnd : public CFrameWnd
{
};
class CApp : public CWinApp
{
public:
virtual BOOL InitInstance()
{
CMainWnd* wnd = new CMainWnd();
if (!wnd->Create(0, _T("test"))) return FALSE;
m_pMainWnd = wnd;
wnd->ShowWindow(SW_SHOW);
wnd->UpdateWindow();
return TRUE;
}
};
CApp app;
It creates simple window with default parameters and title "test". Works perfectly. But then, I want to load my window from resources, so I can put something to it. I replace:
if (!wnd->Create(0, _T("test"))) return FALSE;
with
if (!wnd->LoadFrame(IDD_CLIENTWINDOW)) return FALSE;
(IDD_CLIENTWINDOW is ID of my dialog in resources). LoadFrame returns FALSE, and program exits. There's debug message in output:
Warning: failed to load menu for CFrameWnd.
But there's no menu in dialog IDD_CLIENTWINDOW that I created. How do I load frame correctly? What am I missing?
What you are trying won't work. LoadFrame() with the ID of a dialog won't load a dialog. If you want to use a dialog, make CWnd derive from CDialog or use a view derived from CFormView. Your call to LoadFrame is failing because you don't have a menu resource with the correct ID. But, you're not really trying to do that.
I recommend you use the AppWizard to generate a new application that is either dialog based or CFormView based and see what kind of code is generated. You can look at the code to see what you really want to do.

Resources