From 2351bdda5099aa69f0d62700d708f2f29c824643 Mon Sep 17 00:00:00 2001 From: David Quintana Date: Sun, 24 Aug 2014 14:04:42 +0000 Subject: [PATCH] [RSHELL] * Add a shell DDE skeleton, based on shell32's DDE stubs. svn path=/branches/shell-experiments/; revision=63934 --- base/shell/rshell/CMakeLists.txt | 1 + base/shell/rshell/ShellDDE.cpp | 196 +++++++++++++++++++++++++++++++ base/shell/rshell/rshell.spec | 3 +- 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 base/shell/rshell/ShellDDE.cpp diff --git a/base/shell/rshell/CMakeLists.txt b/base/shell/rshell/CMakeLists.txt index 1d2684f800c..8dc681e63e1 100644 --- a/base/shell/rshell/CMakeLists.txt +++ b/base/shell/rshell/CMakeLists.txt @@ -16,6 +16,7 @@ list(APPEND SOURCE CMergedFolder.cpp CStartMenu.cpp misc.cpp + ShellDDE.cpp ${CMAKE_CURRENT_BINARY_DIR}/rshell.def) add_library(rshell SHARED ${SOURCE}) diff --git a/base/shell/rshell/ShellDDE.cpp b/base/shell/rshell/ShellDDE.cpp new file mode 100644 index 00000000000..97f9e997228 --- /dev/null +++ b/base/shell/rshell/ShellDDE.cpp @@ -0,0 +1,196 @@ +/* + * Shell DDE Handling + * + * Copyright 2004 Robert Shearman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "precomp.h" +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(shelldde); + +/* DDE Instance ID */ +static DWORD dwDDEInst; + +/* String handles */ +static HSZ hszProgmanTopic; +static HSZ hszProgmanService; +static HSZ hszShell; +static HSZ hszAppProperties; +static HSZ hszFolders; + +static BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService) +{ + WCHAR szTopic[MAX_PATH]; + WCHAR szService[MAX_PATH]; + + DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); + DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE); + + DbgPrint("Dde_OnConnect: topic=%S, service=%S\n", szTopic, szService); + + return TRUE; +} + +static void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService) +{ + WCHAR szTopic[MAX_PATH]; + WCHAR szService[MAX_PATH]; + + DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); + DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE); + + DbgPrint("Dde_OnConnectConfirm: hconv=%p, topic=%S, service=%S\n", hconv, szTopic, szService); +} + +static BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService) +{ + WCHAR szTopic[MAX_PATH]; + WCHAR szService[MAX_PATH]; + + DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); + DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE); + + DbgPrint("Dde_OnWildConnect: topic=%S, service=%S\n", szTopic, szService); + + return FALSE; +} + +static HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic, HSZ hszItem) +{ + WCHAR szTopic[MAX_PATH]; + WCHAR szItem[MAX_PATH]; + + DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); + DdeQueryStringW(dwDDEInst, hszItem, szItem, _countof(szItem), CP_WINUNICODE); + + DbgPrint("Dde_OnRequest: uFmt=%d, hconv=%p, topic=%S, item=%S\n", hconv, szTopic, szItem); + + return NULL; +} + +static DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata) +{ + WCHAR szTopic[MAX_PATH]; + WCHAR szCommand[MAX_PATH]; + WCHAR *pszCommand; + + DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); + + pszCommand = (WCHAR*)DdeAccessData(hdata, NULL); + if (!pszCommand) + return DDE_FNOTPROCESSED; + + StringCchCopyW(szCommand, _countof(szCommand), pszCommand); + + DdeUnaccessData(hdata); + + DbgPrint("Dde_OnExecute: hconv=%p, topic=%S, command=%S\n", hconv, szTopic, pszCommand); + + /* + + [ViewFolder("%l", %I, %S)] -- Open a folder in standard mode + [ExploreFolder("%l", %I, %S)] -- Open a folder in "explore" mode (file tree is shown to the left by default) + [FindFolder("%l", %I)] -- Open a folder in "find" mode (search panel is shown to the left by default) + [ShellFile("%1","%1",%S)] -- Execute the contents of the specified .SCF file + + */ + + return DDE_FACK; +} + +static void Dde_OnDisconnect(HCONV hconv) +{ + DbgPrint("Dde_OnDisconnect: hconv=%p\n", hconv); +} + +static HDDEDATA CALLBACK DdeCallback( + UINT uType, + UINT uFmt, + HCONV hconv, + HSZ hsz1, + HSZ hsz2, + HDDEDATA hdata, + ULONG_PTR dwData1, + ULONG_PTR dwData2) +{ + switch (uType) + { + case XTYP_CONNECT: + return (HDDEDATA)(DWORD_PTR)Dde_OnConnect(hsz1, hsz2); + case XTYP_CONNECT_CONFIRM: + Dde_OnConnectConfirm(hconv, hsz1, hsz2); + return NULL; + case XTYP_WILDCONNECT: + return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hsz1, hsz2); + case XTYP_REQUEST: + return Dde_OnRequest(uFmt, hconv, hsz1, hsz2); + case XTYP_EXECUTE: + return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hconv, hsz1, hdata); + case XTYP_DISCONNECT: + Dde_OnDisconnect(hconv); + return NULL; + default: + DbgPrint("DdeCallback: unknown uType=%d\n", uType); + case XTYP_REGISTER: + return NULL; + } +} + +/************************************************************************* + * ShellDDEInit (SHELL32.@) + * + * Registers the Shell DDE services with the system so that applications + * can use them. + * + * PARAMS + * bInit [I] TRUE to initialize the services, FALSE to uninitialize. + * + * RETURNS + * Nothing. + */ +EXTERN_C void WINAPI ShellDDEInit(BOOL bInit) +{ + DbgPrint("ShellDDEInit bInit = %s\n", bInit ? "TRUE" : "FALSE"); + + if (bInit) + { + DdeInitializeW(&dwDDEInst, DdeCallback, CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0); + + hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, L"Progman", CP_WINUNICODE); + hszProgmanService = DdeCreateStringHandleW(dwDDEInst, L"Progman", CP_WINUNICODE); + hszShell = DdeCreateStringHandleW(dwDDEInst, L"Shell", CP_WINUNICODE); + hszAppProperties = DdeCreateStringHandleW(dwDDEInst, L"AppProperties", CP_WINUNICODE); + hszFolders = DdeCreateStringHandleW(dwDDEInst, L"Folders", CP_WINUNICODE); + + DdeNameService(dwDDEInst, hszFolders, 0, DNS_FILTEROFF); + } + else + { + /* unregister all services */ + DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER); + + DdeFreeStringHandle(dwDDEInst, hszFolders); + DdeFreeStringHandle(dwDDEInst, hszAppProperties); + DdeFreeStringHandle(dwDDEInst, hszShell); + DdeFreeStringHandle(dwDDEInst, hszProgmanService); + DdeFreeStringHandle(dwDDEInst, hszProgmanTopic); + + DdeUninitialize(dwDDEInst); + } +} diff --git a/base/shell/rshell/rshell.spec b/base/shell/rshell/rshell.spec index 8616e41cf37..09fbfdff1b0 100644 --- a/base/shell/rshell/rshell.spec +++ b/base/shell/rshell/rshell.spec @@ -2,4 +2,5 @@ @ stdcall CMenuDeskBar_Constructor(ptr ptr); @ stdcall CMenuSite_Constructor(ptr ptr); @ stdcall CMenuBand_Constructor(ptr ptr); -@ stdcall CMergedFolder_Constructor(ptr ptr); \ No newline at end of file +@ stdcall CMergedFolder_Constructor(ptr ptr); +@ stdcall ShellDDEInit(long); \ No newline at end of file