Jump to content
Sign in to follow this  
argumentum

voidtools' everything file search engine IPC

Recommended Posts

The nice ppl of voidtools created Everything Search Engine ( " Locate files and folders by name instantly. " ) :) 
And made a CLI program to search from the command line. They also gave the source code, and reading it, I see the IPC quite familiar.

// // // source for CLI.H
// Everything IPC test

// revision 2:
// fixed command line interpreting '-' as a switch inside text.

// revision 3:
// convert unicode to same code page as console.

// revision 4:
// removed write console because it has no support for piping.

// revision 5:
// added ChangeWindowMessageFilterEx (if available) for admin/user support.

// compiler options
#pragma warning(disable : 4311) // type cast void * to unsigned int
#pragma warning(disable : 4312) // type cast unsigned int to void *
#pragma warning(disable : 4244) // warning C4244: 'argument' : conversion from 'LONG_PTR' to 'LONG', possible loss of data
#pragma warning(disable : 4996) // deprecation

#include <windows.h>
#include <stdio.h>

#include "everything_ipc.h"

#define COPYDATA_IPCTEST_QUERYCOMPLETEW 0

#define MSGFLT_RESET        0
#define MSGFLT_ALLOW        1
#define MSGFLT_DISALLOW     2

typedef struct tagCHANGEFILTERSTRUCT {
  DWORD cbSize;
  DWORD ExtStatus;
} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT;

static void write(wchar_t *text);
static void write_DWORD(DWORD value);
static int wstring_to_int(const wchar_t *s);

int sort = 0;
EVERYTHING_IPC_LIST *sort_list;
HMODULE user32_hdll = 0;

BOOL (WINAPI *pChangeWindowMessageFilterEx)(HWND hWnd,UINT message,DWORD action,PCHANGEFILTERSTRUCT pChangeFilterStruct) = 0;

int wstring_length(const wchar_t *s)
{
    const wchar_t *p;
    
    p = s;
    while(*p)
    {
        p++;
    }
    
    return (int)(p - s);
}

// query everything with search string
int sendquery(HWND hwnd,DWORD num,WCHAR *search_string,int regex,int match_case,int match_whole_word,int match_path)
{
    EVERYTHING_IPC_QUERY *query;
    int len;
    int size;
    HWND everything_hwnd;
    COPYDATASTRUCT cds;
    
    everything_hwnd = FindWindow(EVERYTHING_IPC_WNDCLASS,0);
    if (everything_hwnd)
    {
        len = wstring_length(search_string);
        
        size = sizeof(EVERYTHING_IPC_QUERY) - sizeof(WCHAR) + len*sizeof(WCHAR) + sizeof(WCHAR);
        
        query = (EVERYTHING_IPC_QUERY *)HeapAlloc(GetProcessHeap(),0,size);
        if (query)
        {
            query->max_results = num;
            query->offset = 0;
            query->reply_copydata_message = COPYDATA_IPCTEST_QUERYCOMPLETEW;
            query->search_flags = (regex?EVERYTHING_IPC_REGEX:0) | (match_case?EVERYTHING_IPC_MATCHCASE:0) | (match_whole_word?EVERYTHING_IPC_MATCHWHOLEWORD:0) | (match_path?EVERYTHING_IPC_MATCHPATH:0);
            query->reply_hwnd = hwnd;
            CopyMemory(query->search_string,search_string,(len+1)*sizeof(WCHAR));
        
            cds.cbData = size;
            cds.dwData = EVERYTHING_IPC_COPYDATAQUERY;
            cds.lpData = query;

            if (SendMessage(everything_hwnd,WM_COPYDATA,(WPARAM)hwnd,(LPARAM)&cds) == TRUE)
            {
                HeapFree(GetProcessHeap(),0,query);
                
                return 1;
            }
            else
            {
                write(L"Everything IPC service not running.\n");
            }

            HeapFree(GetProcessHeap(),0,query);
        }
        else
        {
            write(L"failed to allocate ");
            write_DWORD(size);
            write(L" bytes for IPC query.\n");
        }
    }
    else
    {
        // the everything window was not found.
        // we can optionally RegisterWindowMessage("EVERYTHING_IPC_CREATED") and 
        // wait for Everything to post this message to all top level windows when its up and running.
        write(L"Everything IPC window not found, IPC unavailable.\n");
    }

    return 0;
}

int compare_list_items(const void *a,const void *b)
{
    int i;
    
    i = wcsicmp(EVERYTHING_IPC_ITEMPATH(sort_list,a),EVERYTHING_IPC_ITEMPATH(sort_list,b));
    
    if (!i)
    {
        return wcsicmp(EVERYTHING_IPC_ITEMFILENAME(sort_list,a),EVERYTHING_IPC_ITEMFILENAME(sort_list,b));
    }
    else
    if (i > 0)
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

static void write(wchar_t *text)
{
    DWORD mode;
    int wlen;
    DWORD numwritten;
    HANDLE output_handle;
    
    output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
    
    wlen = wstring_length(text);
    
    if (GetConsoleMode(output_handle,&mode))
    {
        WriteConsoleW(output_handle,text,wlen,&numwritten,0);
    }
    else
    {
        char *buf;
        int len;
        
        len = WideCharToMultiByte(GetConsoleCP(),0,text,wlen,0,0,0,0);
        if (len)
        {
            buf = HeapAlloc(GetProcessHeap(),0,len);
            if (buf)
            {
                WideCharToMultiByte(GetConsoleCP(),0,text,wlen,buf,len,0,0);
                
                WriteFile(output_handle,buf,len,&numwritten,0);
                
                HeapFree(GetProcessHeap(),0,buf);
            }
        }
    }
}

static void write_DWORD(DWORD value)
{
    wchar_t buf[256];
    wchar_t *d;
    
    d = buf + 256;
    *--d = 0;

    if (value)
    {
        DWORD i;
        
        i = value;
        
        while(i)
        {
            *--d = '0' + (i % 10);
            
            i /= 10;
        }
    }
    else
    {
        *--d = '0';
    }   
    
    write(d);
}

void listresultsW(EVERYTHING_IPC_LIST *list)
{
    DWORD i;
    
    if (sort)
    {
        sort_list = list;
        qsort(list->items,list->numitems,sizeof(EVERYTHING_IPC_ITEM),compare_list_items);
    }
        
    
    for(i=0;i<list->numitems;i++)
    {
        if (list->items[i].flags & EVERYTHING_IPC_DRIVE)
        {
            write(EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
            write(L"\r\n");
        }
        else
        {
            write(EVERYTHING_IPC_ITEMPATH(list,&list->items[i]));
            write(L"\\");
            write(EVERYTHING_IPC_ITEMFILENAME(list,&list->items[i]));
            write(L"\r\n");
        }
    }
    
    PostQuitMessage(0);
}

// custom window proc
LRESULT __stdcall window_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch(msg)
    {
        case WM_COPYDATA:
        {
            COPYDATASTRUCT *cds = (COPYDATASTRUCT *)lParam;
            
            switch(cds->dwData)
            {
                case COPYDATA_IPCTEST_QUERYCOMPLETEW:
                    listresultsW((EVERYTHING_IPC_LIST *)cds->lpData);
                    return TRUE;
            }
            
            break;
        }
    }
    
    return DefWindowProc(hwnd,msg,wParam,lParam);
}

void help(void)
{
    write(L"-r Search the database using a basic POSIX regular expression.\n");
    write(L"-i Does a case sensitive search.\n");
    write(L"-w Does a whole word search.\n");
    write(L"-p Does a full path search.\n");
    write(L"-h --help Display this help.\n");
    write(L"-n <num> Limit the amount of results shown to <num>.\n");
    write(L"-s Sort by full path.\n");
}

// main entry
int main(int argc,char **argv)
{
    WNDCLASSEX wcex;
    HWND hwnd;
    MSG msg;
    int ret;
    int q;
    wchar_t *search;
    wchar_t *d;
    wchar_t *e;
    wchar_t *s;
    int match_whole_word = 0;
    int match_path = 0;
    int regex = 0;
    int match_case = 0;
    int wasexename = 0;
    int matchpath = 0;
    int i;
    int wargc;
    wchar_t **wargv;
    DWORD num = EVERYTHING_IPC_ALLRESULTS;
    
    ZeroMemory(&wcex,sizeof(wcex));
    wcex.cbSize = sizeof(wcex);
    
    if (!GetClassInfoEx(GetModuleHandle(0),TEXT("IPCTEST"),&wcex))
    {
        ZeroMemory(&wcex,sizeof(wcex));
        wcex.cbSize = sizeof(wcex);
        wcex.hInstance = GetModuleHandle(0);
        wcex.lpfnWndProc = window_proc;
        wcex.lpszClassName = TEXT("IPCTEST");
        
        if (!RegisterClassEx(&wcex))
        {
            write(L"failed to register IPCTEST window class\n");
            
            return 1;
        }
    }
    
    if (!(hwnd = CreateWindow(
        TEXT("IPCTEST"),
        TEXT(""),
        0,
        0,0,0,0,
        0,0,GetModuleHandle(0),0)))
    {
        write(L"failed to create IPCTEST window\n");
        
        return 1;
    }

    // allow the everything window to send a reply.
    user32_hdll = LoadLibrary(L"user32.dll");
    
    if (user32_hdll)
    {
        pChangeWindowMessageFilterEx = (BOOL (WINAPI *)(HWND hWnd,UINT message,DWORD action,PCHANGEFILTERSTRUCT pChangeFilterStruct))GetProcAddress(user32_hdll,"ChangeWindowMessageFilterEx");

        if (pChangeWindowMessageFilterEx)
        {
            pChangeWindowMessageFilterEx(hwnd,WM_COPYDATA,MSGFLT_ALLOW,0);
        }
    }
    
    wargv = CommandLineToArgvW(GetCommandLineW(),&wargc);

    search = HeapAlloc(GetProcessHeap(),0,65536);
    if (!search)
    {
        write(L"failed to allocate ");
        write_DWORD(65536);
        write(L" bytes for search buffer.\n");
        
        if (user32_hdll)
        {
            FreeLibrary(user32_hdll);
        }

        return 1;
    }
    
    d = search;

    // allow room for null terminator
    e = search + (65536 / sizeof(wchar_t)) - 1;
    
    wargc--;
    i = 0;
    for(;;)
    {
        if (i >= wargc) break;
        
        if (wcsicmp(wargv[i+1],L"-r") == 0)
        {
            regex = 1;
        }
        else
        if (wcsicmp(wargv[i+1],L"-i") == 0)
        {
            match_case = 1;
        }
        else
        if (wcsicmp(wargv[i+1],L"-w") == 0)
        {
            match_whole_word = 1;
        }
        else
        if (wcsicmp(wargv[i+1],L"-p") == 0)
        {
            match_path = 1;
        }
        else
        if (wcsicmp(wargv[i+1],L"-s") == 0)
        {
            sort = 1;
        }
        else
        if ((wcsicmp(wargv[i+1],L"-n") == 0) && (i + 1 < wargc))
        {
            i++;
            
            num = wstring_to_int(wargv[i+1]);
        }
        else
        if (wargv[i+1][0] == '-')
        {
            // unknwon command
            help();
            HeapFree(GetProcessHeap(),0,search);
        
            if (user32_hdll)
            {
                FreeLibrary(user32_hdll);
            }

            return 1;
        }
        else
        {
            // keep quotes ?
            q = 0;
            
            s = wargv[i+1];
            while(*s)
            {
                if ((*s == ' ') || (*s == '\t') || (*s == '\r') || (*s == '\n'))
                {
                    q = 1;
                    break
                }
                
                s++;
            }
            
            if ((d != search) && (d < e)) *d++ = ' ';

            if (q)
            {
                if (d < e) *d++ = '"';
            }

            // copy append to search
            s = wargv[i+1];
            while(*s)
            {
                if (d < e) *d++ = *s;
                s++;
            }

            if (q)
            {
                if (d < e) *d++ = '"';
            }
        }
        
        i++;
    }
    
    // null terminate
    *d = 0;

    if (!sendquery(hwnd,num,search,regex,match_case,match_whole_word,match_path)) 
    {
        // send query reports error
        
        HeapFree(GetProcessHeap(),0,search);
        
        if (user32_hdll)
        {
            FreeLibrary(user32_hdll);
        }

        return 1;
    }

    HeapFree(GetProcessHeap(),0,search);

    // message pump
loop:

    // update windows
    if (PeekMessage(&msg,NULL,0,0,0)) 
    {
        ret = (int)GetMessage(&msg,0,0,0);
        if (ret <= 0) goto exit;

        // let windows handle it.
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }           
    else
    {
        WaitMessage();
    }
    
    goto loop;

exit:
    
    if (user32_hdll)
    {
        FreeLibrary(user32_hdll);
    }
        
    return 0;
}

static int wstring_to_int(const wchar_t *s)
{
    const wchar_t *p;
    int value;
    
    p = s;
    value = 0;
    
    while(*p)
    {
        if (!((*p >= '0') && (*p <= '9')))
        {
            break;
        }
        
        value *= 10;
        value += *p - '0';
        p++;
    }
    
    return value;
}
// // // source for everything_ipc.h

// Everything IPC

#ifndef _EVERYTHING_IPC_H_
#define _EVERYTHING_IPC_H_

// C
#ifdef __cplusplus
extern "C" {
#endif

// 1 byte packing for our varible sized structs
#pragma pack(push, 1)

// WM_USER (send to the taskbar notification window)
// SendMessage(FindWindow(EVERYTHING_IPC_WNDCLASS,0),WM_USER,EVERYTHING_IPC_*,lParam)
// version format: major.minor.revision.build 
// example: 1.1.4.309
#define EVERYTHING_IPC_GET_MAJOR_VERSION        0 // int major_version = (int)SendMessage(hwnd,WM_USER,EVERYTHING_IPC_GET_MAJOR_VERSION,0);
#define EVERYTHING_IPC_GET_MINOR_VERSION        1 // int minor_version = (int)SendMessage(hwnd,WM_USER,EVERYTHING_IPC_GET_MINOR_VERSION,0);
#define EVERYTHING_IPC_GET_REVISION             2 // int revision = (int)SendMessage(hwnd,WM_USER,EVERYTHING_IPC_GET_REVISION,0);
#define EVERYTHING_IPC_GET_BUILD_NUMBER         3 // int build = (int)SendMessage(hwnd,WM_USER,EVERYTHING_IPC_GET_BUILD,0);

// find the everything window
#define EVERYTHING_IPC_WNDCLASS         TEXT("EVERYTHING_TASKBAR_NOTIFICATION")

// find a everything search window
#define EVERYTHING_IPC_SEARCH_WNDCLASS  TEXT("EVERYTHING")

// this global window message is sent to all top level windows when everything starts.
#define EVERYTHING_IPC_CREATED          TEXT("EVERYTHING_IPC_CREATED")

// search flags for querys
#define EVERYTHING_IPC_MATCHCASE        0x00000001  // match case
#define EVERYTHING_IPC_MATCHWHOLEWORD   0x00000002  // match whole word
#define EVERYTHING_IPC_MATCHPATH        0x00000004  // include paths in search
#define EVERYTHING_IPC_REGEX            0x00000008  // enable regex

// item flags
#define EVERYTHING_IPC_FOLDER           0x00000001  // The item is a folder. (its a file if not set)
#define EVERYTHING_IPC_DRIVE            0x00000002  // The folder is a drive. Path will be an empty string. 
                                                    // (will also have the folder bit set)

// the WM_COPYDATA message for a query.
#define EVERYTHING_IPC_COPYDATAQUERYA   1
#define EVERYTHING_IPC_COPYDATAQUERYW   2

// all results
#define EVERYTHING_IPC_ALLRESULTS       0xFFFFFFFF // all results

// macro to get the filename of an item
#define EVERYTHING_IPC_ITEMFILENAMEA(list,item) (CHAR *)((CHAR *)(list) + ((EVERYTHING_IPC_ITEMA *)(item))->filename_offset)
#define EVERYTHING_IPC_ITEMFILENAMEW(list,item) (WCHAR *)((CHAR *)(list) + ((EVERYTHING_IPC_ITEMW *)(item))->filename_offset)

// macro to get the path of an item
#define EVERYTHING_IPC_ITEMPATHA(list,item) (CHAR *)((CHAR *)(list) + ((EVERYTHING_IPC_ITEMW *)(item))->path_offset)
#define EVERYTHING_IPC_ITEMPATHW(list,item) (WCHAR *)((CHAR *)(list) + ((EVERYTHING_IPC_ITEMW *)(item))->path_offset)

//
// Varible sized query struct sent to everything.
//
// sent in the form of a WM_COPYDAYA message with EVERYTHING_IPC_COPYDATAQUERY as the 
// dwData member in the COPYDATASTRUCT struct.
// set the lpData member of the COPYDATASTRUCT struct to point to your EVERYTHING_IPC_QUERY struct.
// set the cbData member of the COPYDATASTRUCT struct to the size of the 
// EVERYTHING_IPC_QUERY struct minus the size of a CHAR plus the length of the search string in bytes plus 
// one CHAR for the null terminator.
//
// NOTE: to determine the size of this structure use 
// ASCII: sizeof(EVERYTHING_IPC_QUERYA) - sizeof(CHAR) + strlen(search_string)*sizeof(CHAR) + sizeof(CHAR)
// UNICODE: sizeof(EVERYTHING_IPC_QUERYW) - sizeof(WCHAR) + wcslen(search_string)*sizeof(WCHAR) + sizeof(WCHAR)
//
// NOTE: Everything will only do one query per window.
// Sending another query when a query has not completed 
// will cancel the old query and start the new one. 
//
// Everything will send the results to the reply_hwnd in the form of a 
// WM_COPYDAYA message with the dwData value you specify.
// 
// Everything will return TRUE if successful.
// returns FALSE if not supported.
//
// If you query with EVERYTHING_IPC_COPYDATAQUERYW, the results sent from Everything will be Unicode.
//

typedef struct EVERYTHING_IPC_QUERYW
{
    // the window that will receive the new results.
    HWND reply_hwnd;
    
    // the value to set the dwData member in the COPYDATASTRUCT struct 
    // sent by Everything when the query is complete.
    ULONG_PTR reply_copydata_message;
    
    // search flags (see EVERYTHING_MATCHCASE | EVERYTHING_MATCHWHOLEWORD | EVERYTHING_MATCHPATH)
    DWORD search_flags; 
    
    // only return results after 'offset' results (0 to return the first result)
    // useful for scrollable lists
    DWORD offset; 
    
    // the number of results to return 
    // zero to return no results
    // EVERYTHING_IPC_ALLRESULTS to return ALL results
    DWORD max_results;

    // null terminated string. arbitrary sized search_string buffer.
    WCHAR search_string[1];
    
}EVERYTHING_IPC_QUERYW;

// ASCII version
typedef struct EVERYTHING_IPC_QUERYA
{
    // the window that will receive the new results.
    HWND reply_hwnd;
    
    // the value to set the dwData member in the COPYDATASTRUCT struct 
    // sent by Everything when the query is complete.
    ULONG_PTR reply_copydata_message;
    
    // search flags (see EVERYTHING_MATCHCASE | EVERYTHING_MATCHWHOLEWORD | EVERYTHING_MATCHPATH)
    DWORD search_flags; 
    
    // only return results after 'offset' results (0 to return the first result)
    // useful for scrollable lists
    DWORD offset; 
    
    // the number of results to return 
    // zero to return no results
    // EVERYTHING_IPC_ALLRESULTS to return ALL results
    DWORD max_results;

    // null terminated string. arbitrary sized search_string buffer.
    CHAR search_string[1];
    
}EVERYTHING_IPC_QUERYA;

//
// Varible sized result list struct received from Everything.
//
// Sent in the form of a WM_COPYDATA message to the hwnd specifed in the 
// EVERYTHING_IPC_QUERY struct.
// the dwData member of the COPYDATASTRUCT struct will match the sent
// reply_copydata_message member in the EVERYTHING_IPC_QUERY struct.
// 
// make a copy of the data before returning.
//
// return TRUE if you processed the WM_COPYDATA message.
//

typedef struct EVERYTHING_IPC_ITEMW
{
    // item flags
    DWORD flags;

    // The offset of the filename from the beginning of the list structure.
    // (wchar_t *)((char *)everything_list + everythinglist->name_offset)
    DWORD filename_offset;

    // The offset of the filename from the beginning of the list structure.
    // (wchar_t *)((char *)everything_list + everythinglist->path_offset)
    DWORD path_offset;
    
}EVERYTHING_IPC_ITEMW;

typedef struct EVERYTHING_IPC_ITEMA
{
    // item flags
    DWORD flags;

    // The offset of the filename from the beginning of the list structure.
    // (char *)((char *)everything_list + everythinglist->name_offset)
    DWORD filename_offset;

    // The offset of the filename from the beginning of the list structure.
    // (char *)((char *)everything_list + everythinglist->path_offset)
    DWORD path_offset;
    
}EVERYTHING_IPC_ITEMA;

typedef struct EVERYTHING_IPC_LISTW
{
    // the total number of folders found.
    DWORD totfolders;
    
    // the total number of files found.
    DWORD totfiles;
    
    // totfolders + totfiles
    DWORD totitems;
    
    // the number of folders available.
    DWORD numfolders;
    
    // the number of files available.
    DWORD numfiles;
    
    // the number of items available.
    DWORD numitems;

    // index offset of the first result in the item list.
    DWORD offset;
    
    // arbitrary sized item list. 
    // use numitems to determine the actual number of items available.
    EVERYTHING_IPC_ITEMW items[1];
    
}EVERYTHING_IPC_LISTW;

typedef struct EVERYTHING_IPC_LISTA
{
    // the total number of folders found.
    DWORD totfolders;
    
    // the total number of files found.
    DWORD totfiles;
    
    // totfolders + totfiles
    DWORD totitems;
    
    // the number of folders available.
    DWORD numfolders;
    
    // the number of files available.
    DWORD numfiles;
    
    // the number of items available.
    DWORD numitems;

    // index offset of the first result in the item list.
    DWORD offset;
    
    // arbitrary sized item list. 
    // use numitems to determine the actual number of items available.
    EVERYTHING_IPC_ITEMA items[1];
    
}EVERYTHING_IPC_LISTA;

#ifdef UNICODE
#define EVERYTHING_IPC_COPYDATAQUERY    EVERYTHING_IPC_COPYDATAQUERYW
#define EVERYTHING_IPC_ITEMFILENAME     EVERYTHING_IPC_ITEMFILENAMEW
#define EVERYTHING_IPC_ITEMPATH         EVERYTHING_IPC_ITEMPATHW
#define EVERYTHING_IPC_QUERY            EVERYTHING_IPC_QUERYW
#define EVERYTHING_IPC_ITEM             EVERYTHING_IPC_ITEMW
#define EVERYTHING_IPC_LIST             EVERYTHING_IPC_LISTW
#else
#define EVERYTHING_IPC_COPYDATAQUERY    EVERYTHING_IPC_COPYDATAQUERYA
#define EVERYTHING_IPC_ITEMFILENAME     EVERYTHING_IPC_ITEMFILENAMEA
#define EVERYTHING_IPC_ITEMPATH         EVERYTHING_IPC_ITEMPATHA
#define EVERYTHING_IPC_QUERY            EVERYTHING_IPC_QUERYA
#define EVERYTHING_IPC_ITEM             EVERYTHING_IPC_ITEMA
#define EVERYTHING_IPC_LIST             EVERYTHING_IPC_LISTA
#endif


// restore packing
#pragma pack(pop)

// end extern C
#ifdef __cplusplus
}
#endif

#endif // _EVERYTHING_H_

so, the reason for this posting is: it can be implemented in AutoIt3 B)

I personally can run es.exe and get the results from the command line, that is I, with my knowing, now, some of you can make a beautiful UDF ( and I say some of you, because, I would not know where to start :( )

I use everything for everything, very handy tool. If you ever get to see it work, you'll see how handy it is, mostly if you have many terabytes of files ( or just plain can't remember where a file is at )

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By FrancescoDiMuro
      Good morning Forums 
      In these days, I am working on a project that involved me to use some Windows APIs to obtain some information about Terminal Servers.
      I'm doing this using wtsapi32.dll in a VBA Project, but, the lack of knowledge about few things threated in the articles make this quite difficult to
      implement and understand at the same time.
      The most difficult thing I'm facing is "translating" C/C++ functions or struct in VBA when pointers are used, or pointers of pointers, and so on.
      Since VBA seems to not have a pointer type, to make those functions work I need to implement other functions taken from other DLLs, and this confuses me a lot.
      For example, starting from this code, I splitted all the functions and all the definitions to understand why they are there, and why I need to use them.
      At the end, I've found out that the code I was going to implement starting from the functions provided in the Microsoft Docs won't be ever be able to work without some supplementary functions which are not mentioned anywhere.
      So, I was wondering if someone would please point me out to a good and practical exaplanation about pointers (in general) or specifically for VBA, because I need to use them quite often in these days, and I'd like to understand what I am doing.
      Thanks in advance.

      Best Regards and Stay at home 🏡
       
    • By jamesbowers
      Hi guys! I have a problem that i hope you give me an advice to solve it. I have writing this code and it doesn't run cuz its a problem.
      C2562 'Draw':'void' function returning a vaue.....
      I dont know what to correct.
       

    • By orbs
      for a savvy c++ developer, how hard would it be to compile this into a standalone Win32 console executable?
      i have almost no experience with c++ (and i have no need for any more, since i have AutoIt for pretty much all my requirements). i can compile a simple "hello world" executable (and even embed the mfc dll for backward compatibility). but i am quite interested with that project. your opinion?
       
      P.S. this relates to AutoIt quite simply - once (if and when) i have that project as a standalone executable, i have a GUI made with AutoIt to execute it, then post-process and display the output.
       
    • By Dragonfighter
      Autoit version: 3.3.14.5
      System: Windows 10 Home x64
      C++ IDE: Code::Blocks 17.12
      When I call the Dll that I wrote it give me how return value -1073741819 and exit value 3221225477, I tried changing variables type but it didn't work.
      This is the Autoit code:
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** $dll = DllOpen(@ScriptDir & "\Test.dll") DllCall($dll, "NONE", "TestFunction", "STR", "1 string", "STR", "2 string", "STR", "3 string", "INT", 1) ;Here crash and doesn't show the MsgBox MsgBox(0, "", @error) DllClose($dll) This is the main.cpp code:
      #include <iostream> #include <Windows.h> #include "main.h" using namespace std; extern "C" { DECLDIR void TestFunction(std::string string1, std::string string2, std::string string3, int number1) { std::cout << string1 << std::endl; std::cout << string2 << std::endl; std::cout << string3 << std::endl; std::cout << number1 << std::endl; } } And that is the main.h:
      #ifndef _DLLTEST_H_ #define _DLLTEST_H_ #define DLL_EXPORT #if defined DLL_EXPORT #define DECLDIR __declspec(dllexport) #else #define DECLDIR __declspec(dllimport) #endif extern "C" { DECLDIR void TestFunction(std::string string1, std::string string2, std::string string3, int number1); } #endif  
      And the values of the variables that write to the SciTe console ae completely different.
      Here I attach the console output of the SciTe editor:
      >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\Users\DragonFighter\Desktop\Dll test.au3" /UserParams +>10:30:08 Starting AutoIt3Wrapper v.17.224.935.0 SciTE v.3.7.3.0 Keyboard:00000410 OS:WIN_10/ CPU:X64 OS:X64 Environment(Language:0410) CodePage:0 utf8.auto.check:4 +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\DragonFighter\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\DragonFighter\AppData\Local\AutoIt v3\SciTE >Running AU3Check (3.3.14.5) from:C:\Program Files (x86)\AutoIt3 input:C:\Users\DragonFighter\Desktop\Dll test.au3 +>10:30:08 AU3Check ended.rc:0 >Running:(3.3.14.5):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\DragonFighter\Desktop\Dll test.au3" --> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop �Á+���Uø‰q�‰A�‹O`ÆEÿ�èèÖÿÿƒÄ €}ÿ!>10:30:10 AutoIt3.exe ended.rc:-1073741819 +>10:30:10 AutoIt3Wrapper Finished. >Exit code: 3221225477 Time: 3.414  
      Thanks in advance for every reply.
    • By marcoauto
      Ciao
      I would like to control an ATEM Video Mixer from autoit. I downloaded his SDK which is written in c ++ and I found the sequences to interface, but I was not able to convert the script to self.
      The instructions say to follow this sequence:
      and to connectTo with C++ is:
      string address = "192.168.1.240"; _BMDSwitcherConnectToFailure failureReason = 0; IBMDSwitcher switcher = null; var discovery = new CBMDSwitcherDiscovery(); discovery.ConnectTo(address, out switcher, out failureReason); From Blackmagic SDK:
      IBMDSwitcherDiscovery::ConnectTo method
      The ConnectTo method connects to the specified switcher and returns an IBMDSwitcher object interface for the switcher.
      Syntax HRESULT ConnectTo (string deviceAddress, IBMDSwitcher** switcherDevice, BMDSwitcherConnectToFailure* failReason); Parameters: deviceAddress in Network hostname or IP address of switcher to connect to. switcherDevice out IBMDSwitcher object interface for the connected switcher. failReason out Reason for connection failure as a BMDSwitcherConnectToFailure value. So, I have I tried these solutions but with non success:
      $DllName =@ScriptDir&"\BMDSwitcherAPI.dll" $result = DllCall($DllName, "none", "IBMDSwitcherDiscovery::ConnectTo" & @CRLF) ConsoleWrite("DLLCall Result: " & $result & @CRLF) and I have tried also create an Object (That I think is the best way solution):
      #include <MsgBoxConstants.au3> $oSwitcher=ObjCreate("IBMDSwitcher") If IsObj($oSwitcher) Then MsgBox(64, "", "Object $oSwitcher created successfully") EndIf $oAtem=ObjCreate("IBMDSwitcherDiscovery") If IsObj($oAtem) Then MsgBox(64, "", "Object $oAtem created successfully") EndIf $failureReason =ObjCreate("_BMDSwitcherConnectToFailure") If IsObj($failureReason) Then MsgBox(64, "", "Object $failureReason created successfully") EndIf $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; Install a custom error handler Global $errore,$oSwitcher1 $oAtem.ConnectTo("192.168.1.36",$oSwitcher,$failureReason); ; This is the custom error handler Func MyErrFunc() $HexNumber = Hex($oMyError.number, 8) MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "Windescription is: " & $oMyError.windescription & @CRLF & _ "Source is: " & $oMyError.source & @CRLF & _ "Description is: " & $oMyError.description & @CRLF & _ "Helpfile is: " & $oMyError.helpfile & @CRLF & _ "Helpcontext is: " & $oMyError.helpcontext & @CRLF & _ "Lastdllerror is: " & $oMyError.lastdllerror & @CRLF & _ "Scriptline is: " & $oMyError.scriptline) EndFunc ;==>MyErrFunc But the result is:
      We intercepted a COM Error !
      Number is: 000000A9
      Windescription is: Variable must be of type 'Object'.
      Source is: 
      Description is: 
      Helpfile is: 
      Helpcontext is: 
      Lastdllerror is: 0
      Scriptline is: 17
      The BMDSwitcherAPI.dll is registered in system. Can someone help me?
      Grazie
      Marco
×
×
  • Create New...