summaryrefslogtreecommitdiff
path: root/nt/addpm.c
blob: 395748f8a05c054411bae48fd2263f0f0ebafd79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* Add entries to the GNU Emacs Program Manager folder.
   Copyright (C) 1995 Free Software Foundation, Inc.

   This file is part of GNU Emacs.

   GNU Emacs is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any later
   version.

   GNU Emacs 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 General Public License for
   more details.

   You should have received a copy of the GNU General Public License along
   with GNU Emacs; see the file COPYING.  If not, write to the Free Software
   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/* addpm: Adds entries to the GNU Emacs Program Manager folder.

   	argv[1] = full path to program to execute
	argv[2] = full path to icon for emacs (optional)
 */

#include <windows.h>    // required for all Windows applications
#include <ddeml.h>      // required for DDEML
#include <string.h>     // required for strcpy and strlen

HDDEDATA EXPENTRY dde_callback (WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD);
BOOL              send_shell_command (DWORD, LPSTR);

// Global variables
HANDLE gh_inst;           // current instance

/****************************************************************************
    FUNCTION: WinMain()

    PURPOSE:  Calls initialization function, processes message loop

    PARAMETERS:
        HANDLE h_instance
        HANDLE h_prev_instance
        LPSTR  lp_cmd_line
        int    n_cmd_show

    RETURNS:
        int
****************************************************************************/

int PASCAL 
WinMain (HANDLE h_instance,      // current instance
	 HANDLE h_prev_instance, // previous instance
	 LPSTR  lp_cmd_line,     // command line
	 int    n_cmd_show)      // show-window type (open/icon)
{
  DWORD id_inst = 0L;      // instance identifier
  FARPROC lp_dde_proc;
  char *path, *icon, *s;
  char additem[MAX_PATH*2 + 100];

  gh_inst = h_instance;

  for (path = NULL, s = lp_cmd_line; *s && isspace (*s); s++);
  if (*s) 
    {
      path = s;
      while (*s && !isspace (*s)) 
	s++;
      if (*s) 
	*(s++) = '\0';
    }
  for (icon = NULL; *s && isspace (*s); s++);
  if (*s) 
    {
      icon = s;
      while (*s && !isspace (*s)) 
	s++;
      if (*s) 
	*(s++) = '\0';
    }
  
  lp_dde_proc = MakeProcInstance ((FARPROC) dde_callback, gh_inst);
  
  DdeInitialize (&id_inst,                   // receives instance ID
		 (PFNCALLBACK) lp_dde_proc,  // address of callback function
		 APPCMD_CLIENTONLY,          // this is a client app
		 0L);                        // reserved

  send_shell_command (id_inst, (LPSTR) "[CreateGroup(Gnu Emacs)]");

  send_shell_command (id_inst, (LPSTR) "[ReplaceItem(Emacs)]");

  sprintf (additem, "[AddItem(%s,Emacs%c%s)]",
	   path, (icon ? ',' : ' '), (icon ? icon : ""));
  send_shell_command (id_inst, additem);

  DdeUninitialize (id_inst);

  return (0);
}


/****************************************************************************
    FUNCTION: dde_callback()

    PURPOSE:  Processes messages for DDEML conversation

    PARAMETERS:
        WORD     w_type
        WORD     w_fmt
        HCONV    h_conv
        HSZ      hsz1
        HSZ      hsz2
        HDDEDATA h_data
        DWORD    dw_data1
        DWORD    dw_data2

    RETURNS:
        HDDEDATA
****************************************************************************/

HDDEDATA EXPENTRY 
dde_callback (WORD     w_type,   // transaction type
	      WORD     w_fmt,    // clipboard format
	      HCONV    h_conv,   // handle of the conversation
	      HSZ      hsz1,    // handle of a string
	      HSZ      hsz2,    // handle of a string
	      HDDEDATA h_data,   // handle of a global memory object
	      DWORD    dw_data1, // transaction-specific data
	      DWORD    dw_data2) // transaction-specific data
{
  // Nothing need be done here...
  return (HDDEDATA) NULL;
}


/****************************************************************************
    FUNCTION: send_shell_command()

    PURPOSE:  Sends the given command string to Program Manager

    PARAMETERS:
        LPSTR - pointer to command string

    RETURNS:
        BOOL  - TRUE if this function succeeds, FALSE otherwise
****************************************************************************/

BOOL 
send_shell_command (DWORD id_inst,    // instance identifier
		    LPSTR lp_command) // command string to execute
{
  HSZ      hsz_serv_top;     // Service and Topic name are "PROGMAN"
  HCONV    hconv;            // handle of conversation
  int      n_len;            // length of command string
  HDDEDATA h_data;           // return value of DdeClientTransaction
  DWORD    dw_result;        // result of transaction
  BOOL     b_result = FALSE; // TRUE if this function is successful

  // create string handle to service/topic
  hsz_serv_top = DdeCreateStringHandle (id_inst, "PROGMAN", CP_WINANSI);

  // attempt to start conversation with server app
  if ((hconv = DdeConnect (id_inst, hsz_serv_top, hsz_serv_top, NULL))
      != (HCONV) NULL)
    {
      // get length of the command string
      n_len = lstrlen ((LPSTR) lp_command);

      // send command to server app
      h_data = DdeClientTransaction ((LPBYTE) lp_command, // data to pass
				     n_len + 1,       // length of data
				     hconv,           // handle of conversation
				     (HCONV) NULL,    // handle of name-string
				     CF_TEXT,         // clipboard format
				     XTYP_EXECUTE,    // transaction type
				     1000,            // timeout duration
				     &dw_result);     // transaction result

      if (h_data)
	b_result = TRUE;

      // end conversation
      DdeDisconnect (hconv);
    }

  // free service/topic string handle
  DdeFreeStringHandle (id_inst, hsz_serv_top);

  return b_result;
}