Permalink
Browse files

Maximus5/conemu-inside#12: Query GuiMacro result via callback function.

  ConEmuCD.dll and ConEmuCD64.dll now export `GuiMacro` function.

  Result may be return via BSTR to avoid using of per-process
  environment variable "ConEmuMacroResult".

  Caller is responsible to free the result with `FreeBSTR`.
  Callback function may be passed as argument `ResultCallback`,

  GuiMacro Prototype

    extern "C" int __stdcall GuiMacro(LPCWSTR asInstance, LPCWSTR asMacro, BSTR* bsResult = NULL);

  Function Arguments

    asInstance is the same as right part (after colon) of ConEmuC `-GuiMacro:...` switch.

    asMacro is a GuiMacro itself.

    bsResult must be either NULL, or (BSTR*)-1,
    or a pointer to a variable receiving BSTR.

  Returned Value

    Function returns one of the following integer value

    * CERR_GUIMACRO_SUCCEEDED /* 133 */
    * CERR_GUIMACRO_FAILED    /* 134 */

  GuiMacro Result

    Function `GuiMacro` do not print macro result to StdOut.

    if (bsResult == (BSTR*)-1) then function
    do not return macro result via environment variable.

    if (ResultCallback == NULL) then function returns macro result
    via environment variable "ConEmuMacroResult".

    Otherwise the result allocated with `SysAllocString` and
    returned in *bsResult. Caller must free it with `FreeBSTR`.
  • Loading branch information...
Maximus5 committed Feb 15, 2016
1 parent e0fcead commit ffd3774eb037fb73828ff969464ef57a97dda1a4
Showing with 24 additions and 34 deletions.
  1. +22 −18 src/ConEmuCD/GuiMacro.cpp
  2. +2 −16 src/ConEmuCD/GuiMacro.h
View
@@ -283,29 +283,30 @@ void ArgGuiMacro(CEStr& szArg, MacroInstance& Inst)
}
}
int DoGuiMacro(LPCWSTR asCmdArg, MacroInstance& Inst, GuiMacroFlags Flags, GuiMacroResultCallback ResultCallback /*= NULL*/)
int DoGuiMacro(LPCWSTR asCmdArg, MacroInstance& Inst, GuiMacroFlags Flags, BSTR* bsResult /*= NULL*/)
{
// If neither hMacroInstance nor ghConEmuWnd was set - Macro will fails most likely
_ASSERTE(Inst.hConEmuWnd!=NULL || ghConEmuWnd!=NULL);
wchar_t szErrInst[80] = L"FAILED:Specified ConEmu instance is not found";
wchar_t szErrExec[80] = L"FAILED:Unknown GuiMacro execution error";
// Don't allow to execute on wrong instance
if ((Inst.nPID && !Inst.hConEmuWnd)
|| (Inst.hConEmuWnd && !IsWindow(Inst.hConEmuWnd))
)
{
wchar_t szErr[120] = L"FAILED:Specified ConEmu instance is not found";
if (ResultCallback)
if (bsResult)
{
ResultCallback(gmrInvalidInstance, szErr);
*bsResult = ::SysAllocString(szErrInst);
}
bool bRedirect = false;
bool bPrintError = (Flags & gmf_PrintResult) && ((bRedirect = IsOutputRedirected()) || !gbPrefereSilentMode);
if (bPrintError)
{
if (bRedirect) wcscat_c(szErr, L"\n"); // PowerShell... it does not insert linefeed
_wprintf(szErr);
if (bRedirect) wcscat_c(szErrInst, L"\n"); // PowerShell... it does not insert linefeed
_wprintf(szErrInst);
}
return CERR_GUIMACRO_FAILED;
@@ -331,14 +332,11 @@ int DoGuiMacro(LPCWSTR asCmdArg, MacroInstance& Inst, GuiMacroFlags Flags, GuiMa
{
LPCWSTR pszResult = (pOut->DataSize() >= sizeof(pOut->GuiMacro)) ? pOut->GuiMacro.sMacro : L"";
if (pszResult && *pszResult)
{
iRc = CERR_GUIMACRO_SUCCEEDED; // OK
}
iRc = CERR_GUIMACRO_SUCCEEDED; // OK
if (ResultCallback)
if (bsResult)
{
ResultCallback(gmrOk, pszResult);
*bsResult = ::SysAllocString(pszResult);
}
if (Flags & gmf_SetEnvVar)
@@ -372,10 +370,16 @@ int DoGuiMacro(LPCWSTR asCmdArg, MacroInstance& Inst, GuiMacroFlags Flags, GuiMa
ExecuteFreeResult(pOut);
}
ExecuteFreeResult(pIn);
if ((iRc != CERR_GUIMACRO_SUCCEEDED) && bsResult)
{
*bsResult = ::SysAllocString(szErrExec);
}
return iRc;
}
int __stdcall GuiMacro(LPCWSTR asInstance, LPCWSTR asMacro, GuiMacroResultCallback ResultCallback /*= NULL*/)
int __stdcall GuiMacro(LPCWSTR asInstance, LPCWSTR asMacro, BSTR* bsResult /*= NULL*/)
{
MacroInstance Inst = {};
@@ -388,11 +392,11 @@ int __stdcall GuiMacro(LPCWSTR asInstance, LPCWSTR asMacro, GuiMacroResultCallba
}
GuiMacroFlags Flags = gmf_None;
if (ResultCallback == NULL)
if (bsResult == NULL)
Flags = gmf_SetEnvVar;
else if (ResultCallback == (GuiMacroResultCallback)-1)
ResultCallback = NULL;
else if (bsResult == (BSTR*)-1)
bsResult = NULL;
int iRc = DoGuiMacro(asMacro, Inst, Flags, ResultCallback);
int iRc = DoGuiMacro(asMacro, Inst, Flags, bsResult);
return iRc;
}
View
@@ -48,25 +48,11 @@ const GuiMacroFlags
gmf_PrintResult = 4,
gmf_None = 0;
enum GuiMacroResult
{
// Succeeded
gmrOk = 0,
// Reserved for .Net control module
gmrPending = 1,
gmrDllNotLoaded = 2,
gmrException = 3,
// Bad PID or ConEmu HWND was specified
gmrInvalidInstance = 4,
};
typedef void (__stdcall* GuiMacroResultCallback)(GuiMacroResult code, LPCWSTR result);
void ArgGuiMacro(CEStr& szArg, MacroInstance& Inst);
int DoGuiMacro(LPCWSTR asCmdArg, MacroInstance& Inst, GuiMacroFlags Flags, GuiMacroResultCallback ResultCallback = NULL);
int DoGuiMacro(LPCWSTR asCmdArg, MacroInstance& Inst, GuiMacroFlags Flags, BSTR* bsResult = NULL);
#if defined(__GNUC__)
extern "C"
#endif
int __stdcall GuiMacro(LPCWSTR asInstance, LPCWSTR asMacro, GuiMacroResultCallback ResultCallback = NULL);
int __stdcall GuiMacro(LPCWSTR asInstance, LPCWSTR asMacro, BSTR* bsResult = NULL);

0 comments on commit ffd3774

Please sign in to comment.