Start DDE interface from Explorer Process. Add DDE stubs.
Jeremiah Flerchinger
jeremiah.flerchinger at gmail.com
Tue Feb 10 18:34:18 CST 2009
Explorer.exe now calls ShellDdeInit. Progman stubs will now be started/used in Shell32.
Amazingly any apps with a Progman DDE interface will also be called. Shell32 can handle
all major functionality, but a running progman.exe (for example) will be able to
synchronize internal values with changes made by Shell32.
---
dlls/shell32/dde.c | 42 +++++++++---
programs/explorer/desktop.c | 17 +++++
programs/progman/main.c | 147 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 195 insertions(+), 11 deletions(-)
diff --git a/dlls/shell32/dde.c b/dlls/shell32/dde.c
index 129f753..da8af57 100644
--- a/dlls/shell32/dde.c
+++ b/dlls/shell32/dde.c
@@ -22,6 +22,7 @@
#include "windef.h"
#include "winbase.h"
+#include "winuser.h"
#include "ddeml.h"
#include "shellapi.h"
@@ -40,10 +41,12 @@ static HSZ hszFolders;
static DWORD dwDDEInst;
-static inline BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
+BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
{
if ((hszTopic == hszProgmanTopic) && (hszService == hszProgmanService))
+ {
return TRUE;
+ }
if ((hszTopic == hszProgmanTopic) && (hszService == hszAppProperties))
return TRUE;
if ((hszTopic == hszShell) && (hszService == hszFolders))
@@ -53,25 +56,25 @@ static inline BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
return FALSE;
}
-static inline void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
+void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
{
FIXME("stub\n");
}
-static inline BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
+BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
{
FIXME("stub\n");
return FALSE;
}
-static inline HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
+HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
HSZ hszItem)
{
FIXME("stub\n");
return NULL;
}
-static inline DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
+DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
{
BYTE * pszCommand;
@@ -86,12 +89,12 @@ static inline DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
return DDE_FNOTPROCESSED;
}
-static inline void Dde_OnDisconnect(HCONV hconv)
+void Dde_OnDisconnect(HCONV hconv)
{
FIXME("stub\n");
}
-static HDDEDATA CALLBACK DdeCallback(
+HDDEDATA CALLBACK DdeCallback(
UINT uType,
UINT uFmt,
HCONV hconv,
@@ -101,23 +104,43 @@ static HDDEDATA CALLBACK DdeCallback(
ULONG_PTR dwData1,
ULONG_PTR dwData2)
{
+ char strBuff1[16];
+ char strBuff2[16];
+ if(DdeQueryStringA(dwDDEInst, hsz1, strBuff1, 16, CP_WINANSI) != 0)
+ {
+ if(DdeQueryStringA(dwDDEInst, hsz2, strBuff2, 16, CP_WINANSI) != 0)
+ {
+ FIXME("DdeCallback hszTopic=%s hszItem=%s \n", strBuff1, strBuff2);
+ }
+ else
+ {
+ FIXME("DdeCallback hszTopic=%s \n", strBuff1);
+ }
+ }
switch (uType)
{
case XTYP_CONNECT:
+ FIXME("XTYP_CONNECT \n");
return (HDDEDATA)(DWORD_PTR)Dde_OnConnect(hsz1, hsz2);
case XTYP_CONNECT_CONFIRM:
+ FIXME("XTYP_CONNECT_CONFIRM \n");
Dde_OnConnectConfirm(hconv, hsz1, hsz2);
return NULL;
case XTYP_WILDCONNECT:
+ FIXME("XTYP_WILDCONNECT \n");
return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hsz1, hsz2);
case XTYP_REQUEST:
+ FIXME("DXTYP_REQUEST \n");
return Dde_OnRequest(uFmt, hconv, hsz1, hsz2);
case XTYP_EXECUTE:
+ FIXME("XTYP_EXECUTE \n");
return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hconv, hsz1, hdata);
case XTYP_DISCONNECT:
+ FIXME("XTYP_DISCONNECT \n");
Dde_OnDisconnect(hconv);
return NULL;
default:
+ FIXME("uType=%i \n",uType);
return NULL;
}
}
@@ -147,8 +170,7 @@ void WINAPI ShellDDEInit(BOOL bInit)
{'A','p','p','P','r','o','p','e','r','t','i','e','s',0};
static const WCHAR wszFolders[] = {'F','o','l','d','e','r','s',0};
- DdeInitializeW(&dwDDEInst, DdeCallback, CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
-
+ DdeInitializeW(&dwDDEInst, DdeCallback, APPCLASS_STANDARD, 0);
hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
hszProgmanService = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
hszAsterisk = DdeCreateStringHandleW(dwDDEInst, wszAsterisk, CP_WINUNICODE);
@@ -164,14 +186,12 @@ void WINAPI ShellDDEInit(BOOL bInit)
{
/* unregister all services */
DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
-
DdeFreeStringHandle(dwDDEInst, hszFolders);
DdeFreeStringHandle(dwDDEInst, hszAppProperties);
DdeFreeStringHandle(dwDDEInst, hszShell);
DdeFreeStringHandle(dwDDEInst, hszAsterisk);
DdeFreeStringHandle(dwDDEInst, hszProgmanService);
DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
-
DdeUninitialize(dwDDEInst);
}
}
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 480d245..80e68eb 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -359,6 +359,18 @@ void manage_desktop( WCHAR *arg )
}
}
+ HMODULE libShdocvw;
+ FARPROC ShellDDEInit = NULL;
+
+ libShdocvw = LoadLibraryA("Shdocvw.dll");
+ if (libShdocvw)
+ {
+ ShellDDEInit = (void *)GetProcAddress(libShdocvw, (LPCSTR)118);
+ if (ShellDDEInit != NULL)
+ {
+ ShellDDEInit(TRUE);
+ }
+ }
/* run the desktop message loop */
if (hwnd)
{
@@ -366,6 +378,11 @@ void manage_desktop( WCHAR *arg )
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
}
+
+ if (ShellDDEInit != NULL)
+ {
+ ShellDDEInit(FALSE);
+ }
ExitProcess( 0 );
}
diff --git a/programs/progman/main.c b/programs/progman/main.c
index 83a346c..4c34b98 100644
--- a/programs/progman/main.c
+++ b/programs/progman/main.c
@@ -29,6 +29,13 @@
GLOBALS Globals;
+/* String handles */
+static HSZ hszProgmanTopic;
+static HSZ hszProgmanService;
+static HSZ hszAppProperties;
+/* DDE Instance ID */
+static DWORD dwDDEInst;
+
static VOID MAIN_CreateGroups(void);
static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
static ATOM MAIN_RegisterMainWinClass(void);
@@ -40,6 +47,94 @@ static VOID WineWarranty(HWND Wnd);
#define BUFFER_SIZE 1000
+void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
+{
+ printf("Progman.exe: Dde_OnConnectConfirm stub\n");
+}
+
+BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
+{
+ printf("Progman.exe: Dde_OnWildConnect stub\n");
+ return FALSE;
+}
+
+HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
+ HSZ hszItem)
+{
+ printf("Progman.exe: Dde_OnRequest stub\n");
+ return NULL;
+}
+
+DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
+{
+ BYTE * pszCommand;
+
+ pszCommand = DdeAccessData(hdata, NULL);
+ if (!pszCommand)
+ return DDE_FNOTPROCESSED;
+
+ printf("Progman.exe: Dde_OnExecute stub: %s\n", pszCommand);
+
+ DdeUnaccessData(hdata);
+
+ return DDE_FNOTPROCESSED;
+}
+
+void Dde_OnDisconnect(HCONV hconv)
+{
+ printf("Progman.exe: Dde_OnDisconnect stub\n");
+}
+
+static HDDEDATA CALLBACK DdeCallback(UINT wType, UINT fmt, HCONV hConv, HSZ hszTopic, HSZ hszItem, HDDEDATA hData, DWORD dwData1, DWORD dwData2)
+{
+ char strBuff1[16];
+ char strBuff2[16];
+ if(DdeQueryString(dwDDEInst, hszTopic, strBuff1, 16, CP_WINANSI) != 0)
+ {
+ if(DdeQueryString(dwDDEInst, hszItem, strBuff2, 16, CP_WINANSI) != 0)
+ {
+ printf("Progman.exe: stub DdeCallback hszTopic=%s hszItem=%s \n", strBuff1, strBuff2);
+ }
+ else
+ {
+ printf("Progman.exe: stub DdeCallback hszTopic=%s \n", strBuff1);
+ }
+ }
+ switch (wType)
+ {
+ case XTYP_CONNECT:
+ printf("Progman.exe: XTYP_CONNECT stub return TRUE - Note DDE functionality is limited\n");
+ if ((hszTopic == hszProgmanTopic) && (hszItem == hszProgmanService))
+ {
+ printf("Progman.exe: XTYP_CONNECT stub return TRUE - Note DDE functionality is limited\n");
+ return TRUE;
+ }
+ printf("Progman.exe: XTYP_CONNECT stub return FALSE - DDE connection rejected\n");
+ return FALSE;
+ case XTYP_CONNECT_CONFIRM:
+ printf("Progman.exe: XTYP_CONNECT_CONFIRM stub\n");
+ Dde_OnConnectConfirm(hConv, hszTopic, hszItem);
+ return NULL;
+ case XTYP_WILDCONNECT:
+ printf("Progman.exe: XTYP_WILDCONNECT stub\n");
+ return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hszTopic, hszItem);
+ case XTYP_REQUEST:
+ printf("Progman.exe: XTYP_REQUEST stub\n");
+ return Dde_OnRequest(fmt, hConv, hszTopic, hszItem);
+ case XTYP_EXECUTE:
+ printf("Progman.exe: XTYP_EXECUTE stub\n");
+ return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hConv, hszTopic, hData);
+ case XTYP_DISCONNECT:
+ printf("Progman.exe: XTYP_DISCONNECT stub\n");
+ Dde_OnDisconnect(hConv);
+ return NULL;
+ default:
+ printf("Progman.exe: XTYP type=0h%X (%i) default stub\n", wType, wType);
+ return NULL;
+ }
+}
+
+
/***********************************************************************
*
* WinMain
@@ -48,6 +143,9 @@ static VOID WineWarranty(HWND Wnd);
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
{
MSG msg;
+ static const WCHAR wszProgman[] = {'P','R','O','G','M','A','N',0};
+ static const WCHAR wszAppProperties[] =
+ {'A','p','p','P','r','o','p','e','r','t','i','e','s',0};
Globals.lpszIniFile = "progman.ini";
Globals.lpszIcoFile = "progman.ico";
@@ -56,6 +154,12 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show
Globals.hGroups = 0;
Globals.hActiveGroup = 0;
+ /* start dde */
+ DdeInitializeW(&dwDDEInst, DdeCallback, APPCLASS_STANDARD, 0);
+ hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
+ hszProgmanService = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
+ DdeNameService(dwDDEInst, hszProgmanService, 0, DNS_REGISTER);
+
/* Read Options from `progman.ini' */
Globals.bAutoArrange =
GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
@@ -102,6 +206,14 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show
TranslateMessage (&msg);
DispatchMessage (&msg);
}
+
+ /* close dde*/
+ DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
+ DdeFreeStringHandle(dwDDEInst, hszProgmanService);
+ DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
+ DdeFreeStringHandle(dwDDEInst, hszAppProperties);
+
+ DdeUninitialize(dwDDEInst);
return 0;
}
@@ -167,6 +279,13 @@ VOID MAIN_AutoStart(void)
static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
+ int maxstrcount = 255;
+ int strcount;
+ char strService[maxstrcount];
+ char strTopic[maxstrcount];
+ UINT_PTR uiLo, uiHi;
+ ATOM atomApplication;
+ ATOM atomTopic;
#if 0
printf("M %4.4x %4.4x\n", msg, wParam);
#endif
@@ -190,6 +309,34 @@ static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
case WM_DESTROY:
PostQuitMessage (0);
break;
+ case WM_DDE_INITIATE:
+ uiLo = LOWORD(lParam);
+ uiHi = HIWORD(lParam);
+ strcount = GlobalGetAtomName(uiLo, strService, maxstrcount);
+ strcount = GlobalGetAtomName(uiHi, strTopic, maxstrcount);
+ printf("Progman.exe: WM_DDE_INITIATE stub Service=%s Topic=%s \n", strService, strTopic);
+ break;
+ case WM_DDE_POKE:
+ printf("Progman.exe: WM_DDE_POKE stub \n");
+ break;
+ case WM_DDE_EXECUTE:
+ printf("Progman.exe: WM_DDE_EXECUTE stub \n");
+ break;
+ case WM_DDE_DATA:
+ printf("Progman.exe: WM_DDE_DATA stub \n");
+ break;
+ case WM_DDE_ADVISE:
+ printf("Progman.exe: WM_DDE_ADVISE stub \n");
+ break;
+ case WM_DDE_UNADVISE:
+ printf("Progman.exe: WM_DDE_UNADVISE stub \n");
+ break;
+ case WM_DDE_REQUEST:
+ printf("Progman.exe: WM_DDE_REQUEST stub \n");
+ break;
+ case WM_DDE_TERMINATE:
+ printf("Progman.exe: WM_DDE_TERMINATE stub \n");
+ break;
}
return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
}
--
1.5.6.3
More information about the wine-patches
mailing list