NO

Author Topic: Two problems  (Read 4964 times)

czerny

  • Guest
Two problems
« on: August 19, 2014, 12:32:14 PM »
I have two problems which I can not find a solution. It would be nice if anyone could give me some hints.

Problem 1: I have a menu (by resource) with two popup menus: 'Test' and 'Help'. I want to append a third popup 'Plugins' dynamically. The problem is, that I want to have the 'Help' popup as the last and the 'Plugins' popup as the second entry!

Problem 2: See my WinMain messageloop. The popup 'Test' has an item 'Doit' which can activatet by the shortcut Strg-D (Ctrl-D in english). But if I uncomment the two code pieces
Code: [Select]
[color=red]PLUGINS P = SetPlugInMenu(hwnd);[/color] // <---

HACCEL haccel = LoadAccelerators(ghInstance, MAKEINTRESOURCE(IDC_ACCEL));

    /* Pump messages until we are done */
    while (GetMessage(&msg, NULL, 0, 0)>0)
    {
if(!TranslateAccelerator(hwnd, haccel, &msg)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
}
    }

[color=red]FreePlugins(P); [/color]

the shortcut is not working anymore. TranslateAccelerator is never true.

There will come a third problem. The plugins shall have their own shortcuts. But this is in the future!  :)

czerny

  • Guest
Re: Two problems
« Reply #1 on: August 19, 2014, 02:32:54 PM »
I have a working solution for Problem 1:

Code: [Select]
BOOL InsertPopupMenu(HMENU hm, int pos, char *string, HMENU hsm)
{
MENUITEMINFO mii = {0};

    mii.cbSize = sizeof(MENUITEMINFO);
    mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
    mii.fType = MFT_STRING;
    mii.hSubMenu = hsm;
    mii.dwTypeData = string;
    mii.cch = strlen(string);

if (pos == -1)
    return InsertMenuItem(hm, GetMenuItemCount(hm), TRUE, &mii);
else
    return InsertMenuItem(hm, pos, TRUE, &mii);
}

laurro

  • Guest
Re: Two problems
« Reply #2 on: August 19, 2014, 04:54:44 PM »
Czerny the function Main_OnCommand() should return zero if it processes WM_COMMAND.
I never liked windowsx and in fact I never use it.

Code: [Select]
static int Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id)
{
case IDM_DOIT:
MessageBox(0, "Doit", "Info", MB_OK);
return 0; // or break;
case IDM_ABOUT:
DialogBox(ghInstance, MAKEINTRESOURCE(DLG_ABOUT), hwnd, (DLGPROC)AboutDlgProc);
break;
default:
return 0;
}
return 0;
}

Laur

czerny

  • Guest
Re: Two problems
« Reply #3 on: August 19, 2014, 05:03:20 PM »
I have done the following:
Code: [Select]
P = SetPlugInMenu(hwnd); // <---

haccel = LoadAccelerators(ghInstance, MAKEINTRESOURCE(IDC_ACCEL));

char s[200]="";
ACCEL accel[10];
int num = CopyAcceleratorTable(haccel, NULL, 0);
CopyAcceleratorTable(haccel, &accel[0], num);
for (int i=0; i<num; i++){
sprintf(s,"[%d] %d %d %d", i, accel[i].fVirt, accel[i].key, accel[i].cmd);
MessageBox(0,s,"Accelerator",MB_OK);
}

With
Code: [Select]
IDC_ACCEL ACCELERATORS
{
  68, 6002, VIRTKEY, CONTROL
}

I get num==1:
  • 9 68 6002

which looks ok to me.

With
Code: [Select]
IDC_ACCEL ACCELERATORS
{
  68, 6002, VIRTKEY, CONTROL
  48, 6500, VIRTKEY, CONTROL
  49, 6501, VIRTKEY, CONTROL
}
I get num==3:
  • 9 68 6002, [1] 9 48 6500, [2] 9 49 6501 

which looks ok to me, too.

czerny

  • Guest
Re: Two problems
« Reply #4 on: August 19, 2014, 05:06:36 PM »
Czerny the function Main_OnCommand() should return zero if it processes WM_COMMAND.
I never liked windowsx and in fact I never use it.
It does return 0:
Code: [Select]
#define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)  ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0)

laurro

  • Guest
Re: Two problems
« Reply #5 on: August 19, 2014, 05:59:08 PM »
Yes you're right, my mistake.

Laur

laurro

  • Guest
Re: Two problems
« Reply #6 on: August 20, 2014, 02:44:03 PM »
I think this time I get it right. The problem is your calling conventions, you use __cdecl in the
dll but when you call InitPlugin() you use FARPROCs (__stdcall). At some level things get messed up,
stack coruption probably . This is a working version of SetPlugInMenu(), sorry for my first replay.

Laur

Code: [Select]
PLUGINS SetPlugInMenu(HWND hwnd)
{
PLUGINS P = malloc(sizeof(struct _Plugins));
P->num = 0;
P->path = NULL;

HMODULE hmod;
//FARPROC PLG_Init, PLG_Free;
typedef char *(__cdecl *f1) (char *, int);
typedef void (__cdecl *f2) (void);
f1 PLG_Init;
f2 PLG_Free;

char dir[MAX_PATH], search[MAX_PATH], plugname[MAX_PATH];

GetSearchPath(dir, search);

HMENU hm = GetMenu(hwnd);
HMENU hsm = CreateMenu();

MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_DATA;
mii.fType = MFT_STRING;
mii.hSubMenu = hsm;
mii.dwTypeData = "Plugins";
mii.cch = strlen("Plugins");

InsertMenuItem(hm, 1, TRUE, &mii);

WIN32_FIND_DATA find_data;
BOOL goon = TRUE;
HANDLE hfind = FindFirstFile(search, &find_data);

while (hfind != INVALID_HANDLE_VALUE && goon)
{
strcpy_s(plugname, MAX_PATH, dir);
strcat_s(plugname, MAX_PATH, find_data.cFileName);

hmod = LoadLibrary(plugname);

if (hmod)
{
PLG_Init = (f1)GetProcAddress(hmod, "InitPlugin");
PLG_Free = (f2)GetProcAddress(hmod, "FreePlugin");

if (PLG_Init && PLG_Free)
{
char MenuItem[100];
PLG_Init(MenuItem, 100);
if (P->num < 10)
{
sprintf(MenuItem, "%s\tStrg-%d", MenuItem, P->num);
}
AppendMenu(hsm, MF_STRING, IDM_PLUGITEM + P->num++, MenuItem);
P->path = realloc(P->path, P->num * sizeof(char *));
P->path[P->num - 1] = malloc(strlen(plugname) + 1);
strcpy(P->path[P->num - 1], plugname);
}
FreeLibrary(hmod); // we load them later as needed!
}
goon = FindNextFile(hfind, &find_data);
}

SetMenu(hwnd, hm);
return P;
}


czerny

  • Guest
Re: Two problems
« Reply #7 on: August 20, 2014, 03:51:04 PM »
I think this time I get it right. The problem is your calling conventions, you use __cdecl in the
dll but when you call InitPlugin() you use FARPROCs (__stdcall).
Yes! You are right! Thank you very much!  :D