VC++プログラムから SendTo 送るメニューを表示させたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
demaemonn_1932

VC++プログラムから SendTo 送るメニューを表示させたい

#1

投稿記事 by demaemonn_1932 » 7年前

VC++2008でWIN32をやっていますCベースです
COMオビジェクト利用でも結構です
VC++プログラムから SendTo 送るメニューを表示できませんでしょうか
テキストで選択した範囲のファイル名フルパス等を
SendTo 送るメニューに送信して開きたいのです
よろしくお願いします。

かずま

Re: VC++プログラムから SendTo 送るメニューを表示させたい

#2

投稿記事 by かずま » 7年前

期待されていることと違うかもしれませんが。

コード:

#include <stdio.h>   // fgets, sprintf, puts, printf
#include <stdlib.h>  // getenv, system
#include <string.h>  // strchr, strdup
#include <windows.h> // FindFirstFile, FindNextFile
 
int main(void)
{
    WIN32_FIND_DATA ffd;
    HANDLE h;
    char path[MAX_PATH], name[MAX_PATH], *dir, *p, *a[100];
    int i, n = 0;

    dir = getenv("APPDATA");
    if (!dir) return puts("getenv failed"), 1;

    printf("filename> ");
    if (!fgets(name, sizeof name, stdin)) return puts("fgets failed"), 2;
    p = strchr(name, '\n');
    if (p) *p = '\0';

    sprintf(path, "%s/Microsoft/Windows/SendTo/*", dir);
    h = FindFirstFile(path, &ffd);
    if (h == INVALID_HANDLE_VALUE) return puts("FindFirstFile failed"), 3;
    do {
        if (ffd.cFileName[0] != '.') {
            a[n++] = strdup(ffd.cFileName);
            printf("%2d: %s\n", n, ffd.cFileName);
        }
    } while (FindNextFile(h, &ffd));

    while (1) {
        char buf[256];
        printf(">> ");
        if (!fgets(buf, sizeof buf, stdin)) return puts("fgets failed"), 4;
        if (sscanf(buf, "%d", &i) == 1 && i >= 1 && i <= n) break;
    }
    sprintf(path, "%s/Microsoft/Windows/SendTo/%s %s", dir, a[i-1], name);
    system(path);
    return 0;
}
準備
・エクスプローラで shell:sendto を指定すると、SendToフォルダが
 開くので、そこにメモ帳のショートカットを置く。
・テキストファイル c:/tmp/a.c を用意する。

実行例

コード:

filename> c:/tmp/a.c
 1: Bluetooth ファイル転送.LNK
 2: Compressed (zipped) Folder.ZFSendToTarget
 3: Desktop (create shortcut).DeskLink
 4: Desktop.ini
 5: Fax Recipient.lnk
 6: FAX 受信者.lnk
 7: Mail Recipient.MAPIMail
 8: Notepad.lnk
 9: ドキュメント.mydocs
>> 8
メモ帳(Notepad)が開いて、c:/tmp/a.c が表示されます。

かずま

Re: VC++プログラムから SendTo 送るメニューを表示させたい

#3

投稿記事 by かずま » 7年前

[quote="かずま" id=3,20041,150116]

コード:

    sprintf(path, "%s/Microsoft/Windows/SendTo/%s %s", dir, a[i-1], name);
ファイル名にスペースがあるかもしれないので、

コード:

	sprintf(path, "%s/Microsoft/Windows/SendTo/\"%s\" \"%s\"", dir, a[i-1], name);
のほうがいいでしょう。

demaemonn_1932

Re: VC++プログラムから SendTo 送るメニューを表示させたい

#4

投稿記事 by demaemonn_1932 » 7年前

かずまさん
ソースコードありがとうございます
早速組み込みます
///////////////////////////////////////////////////////////////////////
1.SendToフォルダを特定する
2.中の登録アプリをメニューに表示する
3.登録アプリが選択されたら起動させてパラメータを渡す
///////////////////////////////////////////////////////////////////////

かずま

Re: VC++プログラムから SendTo 送るメニューを表示させたい

#5

投稿記事 by かずま » 7年前

コンソールアプリではなく、Windows の PopupMenu を使うようにしてみました。
また、system を使うと、コマンドプロンプトのウィンドウが開くので
ShellExecute に変えてみました。

コード:

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>  // sprintf
#include <stdlib.h> // getenv

#define CHILD_ID   100
#define MENU_ITEM  200

HWND hEdit;
HMENU hMenu;
int nItem;
char *dir = 0;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wp, LPARAM lp)
{
    switch (message) {
    case WM_CREATE: {
        WIN32_FIND_DATA wfd;
        HANDLE h;
        char path[MAX_PATH];
        dir = getenv("APPDATA");
        if (!dir) return 1;
        sprintf(path, "%s/Microsoft/Windows/SendTo/*", dir);
        h = FindFirstFile(path, &wfd);
        if (h == INVALID_HANDLE_VALUE) return 2;
        hMenu = CreatePopupMenu();
        nItem = 0;
        do {
            if (wfd.cFileName[0] != '.')
                AppendMenu(hMenu, MF_STRING, MENU_ITEM + nItem++, wfd.cFileName);
        } while (FindNextFile(h, &wfd));
        break;
    }
    case WM_RBUTTONDOWN: {
        POINT pt;
        pt.x = LOWORD(lp);
        pt.y = HIWORD(lp);
        ClientToScreen(hWnd, &pt);
        TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hWnd, NULL);
        break;
    }
    case WM_COMMAND: {
        char path[MAX_PATH], app[MAX_PATH], name[MAX_PATH];
        WORD id = LOWORD(wp);
        if (id < MENU_ITEM || id >= MENU_ITEM + nItem)
            return DefWindowProc(hWnd, message, wp, lp);
        GetWindowText(hEdit, name, sizeof name);
        GetMenuString(hMenu, id, app, sizeof app, 0);
        sprintf(path, "%s/Microsoft/Windows/SendTo/%s", dir, app);
        ShellExecute(NULL, "open", path, name, NULL, SW_SHOWNORMAL);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wp, lp);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE h, char *s, int nCmdShow)
{
    HWND hWnd;
    MSG msg;
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "test";
    RegisterClass(&wc);

    hWnd = CreateWindow("test", "SendTo", WS_OVERLAPPEDWINDOW,
        160, 120, 480, 240, NULL, NULL, hInst, NULL);
    hEdit = CreateWindow("edit", NULL,
        WS_VISIBLE | WS_CHILD |ES_LEFT | ES_AUTOHSCROLL,
        40, 40, 400, 20, hWnd, (HMENU)CHILD_ID, hInst, NULL);
    CreateWindow("static",
        "Enter a file path and click here with the right button",
        SS_SIMPLE | WS_CHILD | WS_VISIBLE,
        50, 80, 360, 60, hWnd, NULL, hInst, NULL);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    UnregisterClass("test", hInst);
    return msg.wParam;
}
エクスプローラでファイルを右クリックして表示する「送る」
メニューは Notepad.lnk を「メモ帳」と表示しますね。
これはどうなっているんでしょうか。

demaemonn_1932

Re: VC++プログラムから SendTo 送るメニューを表示させたい

#6

投稿記事 by demaemonn_1932 » 7年前

かずまさん
Windowで表示でききるようにありがとうございました
実際やってみてリストが取得できました
さらに簡単な方法がないかと、
http://hp.vector.co.jp/authors/VA016117/explorer5.html
等も出まして、いろいろ参考にしたいと思います
ありがとうございました。

返信

“C言語何でも質問掲示板” へ戻る