mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 14:39:24 -05:00
ANSI remote printer support. Raw mode only.
[originally from svn r1581]
This commit is contained in:
parent
04fba1e540
commit
ae476d5567
1
Makefile
1
Makefile
@ -94,6 +94,7 @@ RES=res
|
|||||||
##-- objects putty puttytel
|
##-- objects putty puttytel
|
||||||
GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
|
GOBJS1 = window.$(OBJ) windlg.$(OBJ) winctrls.$(OBJ) terminal.$(OBJ)
|
||||||
GOBJS2 = sizetip.$(OBJ) wcwidth.$(OBJ) unicode.$(OBJ) logging.$(OBJ)
|
GOBJS2 = sizetip.$(OBJ) wcwidth.$(OBJ) unicode.$(OBJ) logging.$(OBJ)
|
||||||
|
GOBJS3 = printing.$(OBJ)
|
||||||
##-- objects putty puttytel plink
|
##-- objects putty puttytel plink
|
||||||
LOBJS1 = telnet.$(OBJ) raw.$(OBJ) rlogin.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
|
LOBJS1 = telnet.$(OBJ) raw.$(OBJ) rlogin.$(OBJ) ldisc.$(OBJ) winnet.$(OBJ)
|
||||||
##-- objects putty plink
|
##-- objects putty plink
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
\versionid $Id: config.but,v 1.28 2002/03/09 11:47:39 simon Exp $
|
\versionid $Id: config.but,v 1.29 2002/03/09 17:59:15 simon Exp $
|
||||||
|
|
||||||
\C{config} Configuring PuTTY
|
\C{config} Configuring PuTTY
|
||||||
|
|
||||||
@ -380,6 +380,38 @@ this configuration option to override its choice: you can force
|
|||||||
local line editing to be turned on, or force it to be turned off,
|
local line editing to be turned on, or force it to be turned off,
|
||||||
instead of relying on the automatic detection.
|
instead of relying on the automatic detection.
|
||||||
|
|
||||||
|
\S{config-printing} Remote-controlled printing
|
||||||
|
|
||||||
|
\cfg{winhelp-topic}{terminal.printing}
|
||||||
|
|
||||||
|
A lot of VT100-compatible terminals support printing under control
|
||||||
|
of the remote server. PuTTY supports this feature as well, but it is
|
||||||
|
turned off by default.
|
||||||
|
|
||||||
|
To enable remote-controlled printing, choose a printer from the
|
||||||
|
\q{Printer to send ANSI printer output to} drop-down list box. This
|
||||||
|
should allow you to select from all the printers you have installed
|
||||||
|
drivers for on your computer. Alternatively, you can type the
|
||||||
|
network name of a networked printer (for example,
|
||||||
|
\c{\\\\printserver\\printer1}) even if you haven't already
|
||||||
|
installed a driver for it on your own machine.
|
||||||
|
|
||||||
|
When the remote server attempts to print some data, PuTTY will send
|
||||||
|
that data to the printer \e{raw} - without translating it,
|
||||||
|
attempting to format it, or doing anything else to it. It is up to
|
||||||
|
you to ensure your remote server knows what type of printer it is
|
||||||
|
talking to.
|
||||||
|
|
||||||
|
Since PuTTY sends data to the printer raw, it cannot offer options
|
||||||
|
such as portrait versus landscape, print quality, or paper tray
|
||||||
|
selection. All these things would be done by your PC printer driver
|
||||||
|
(which PuTTY bypasses); if you need them done, you will have to find
|
||||||
|
a way to configure your remote server to do them.
|
||||||
|
|
||||||
|
To disable remote printing again, choose \q{None (printing
|
||||||
|
disabled)} from the printer selection list. This is the default
|
||||||
|
state.
|
||||||
|
|
||||||
\H{config-keyboard} The Keyboard panel
|
\H{config-keyboard} The Keyboard panel
|
||||||
|
|
||||||
The Keyboard configuration panel allows you to control the behaviour
|
The Keyboard configuration panel allows you to control the behaviour
|
||||||
|
13
putty.h
13
putty.h
@ -336,6 +336,7 @@ typedef struct {
|
|||||||
int sunken_edge;
|
int sunken_edge;
|
||||||
int window_border;
|
int window_border;
|
||||||
char answerback[256];
|
char answerback[256];
|
||||||
|
char printer[128];
|
||||||
/* Colour options */
|
/* Colour options */
|
||||||
int try_palette;
|
int try_palette;
|
||||||
int bold_colour;
|
int bold_colour;
|
||||||
@ -609,4 +610,16 @@ extern int console_batch_mode;
|
|||||||
extern char *console_password;
|
extern char *console_password;
|
||||||
int console_get_line(const char *prompt, char *str, int maxlen, int is_pw);
|
int console_get_line(const char *prompt, char *str, int maxlen, int is_pw);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exports from printing.c.
|
||||||
|
*/
|
||||||
|
typedef struct printer_enum_tag printer_enum;
|
||||||
|
typedef struct printer_job_tag printer_job;
|
||||||
|
printer_enum *printer_start_enum(int *nprinters);
|
||||||
|
char *printer_get_name(printer_enum *, int);
|
||||||
|
void printer_finish_enum(printer_enum *);
|
||||||
|
printer_job *printer_start_job(char *printer);
|
||||||
|
void printer_job_data(printer_job *, void *, int);
|
||||||
|
void printer_finish_job(printer_job *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -261,6 +261,7 @@ void save_settings(char *section, int do_host, Config * cfg)
|
|||||||
write_setting_s(sesskey, buf, buf2);
|
write_setting_s(sesskey, buf, buf2);
|
||||||
}
|
}
|
||||||
write_setting_s(sesskey, "LineCodePage", cfg->line_codepage);
|
write_setting_s(sesskey, "LineCodePage", cfg->line_codepage);
|
||||||
|
write_setting_s(sesskey, "Printer", cfg->printer);
|
||||||
write_setting_i(sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
|
write_setting_i(sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
|
||||||
write_setting_i(sesskey, "ScrollBar", cfg->scrollbar);
|
write_setting_i(sesskey, "ScrollBar", cfg->scrollbar);
|
||||||
write_setting_i(sesskey, "ScrollBarFullScreen", cfg->scrollbar_in_fullscreen);
|
write_setting_i(sesskey, "ScrollBarFullScreen", cfg->scrollbar_in_fullscreen);
|
||||||
@ -503,6 +504,7 @@ void load_settings(char *section, int do_host, Config * cfg)
|
|||||||
*/
|
*/
|
||||||
gpps(sesskey, "LineCodePage", "", cfg->line_codepage,
|
gpps(sesskey, "LineCodePage", "", cfg->line_codepage,
|
||||||
sizeof(cfg->line_codepage));
|
sizeof(cfg->line_codepage));
|
||||||
|
gpps(sesskey, "Printer", "", cfg->printer, sizeof(cfg->printer));
|
||||||
gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
|
gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
|
||||||
gppi(sesskey, "ScrollBar", 1, &cfg->scrollbar);
|
gppi(sesskey, "ScrollBar", 1, &cfg->scrollbar);
|
||||||
gppi(sesskey, "ScrollBarFullScreen", 0, &cfg->scrollbar_in_fullscreen);
|
gppi(sesskey, "ScrollBarFullScreen", 0, &cfg->scrollbar_in_fullscreen);
|
||||||
|
112
terminal.c
112
terminal.c
@ -115,6 +115,10 @@ static int vt52_bold; /* Force bold on non-bold colours */
|
|||||||
static int utf_state; /* Is there a pending UTF-8 character */
|
static int utf_state; /* Is there a pending UTF-8 character */
|
||||||
static int utf_char; /* and what is it so far. */
|
static int utf_char; /* and what is it so far. */
|
||||||
static int utf_size; /* The size of the UTF character. */
|
static int utf_size; /* The size of the UTF character. */
|
||||||
|
static int printing, only_printing; /* Are we doing ANSI printing? */
|
||||||
|
static int print_state; /* state of print-end-sequence scan */
|
||||||
|
static bufchain printer_buf; /* buffered data for printer */
|
||||||
|
static printer_job *print_job;
|
||||||
|
|
||||||
static int xterm_mouse; /* send mouse messages to app */
|
static int xterm_mouse; /* send mouse messages to app */
|
||||||
|
|
||||||
@ -206,6 +210,7 @@ static void erase_lots(int, int, int);
|
|||||||
static void swap_screen(int);
|
static void swap_screen(int);
|
||||||
static void update_sbar(void);
|
static void update_sbar(void);
|
||||||
static void deselect(void);
|
static void deselect(void);
|
||||||
|
static void term_print_finish(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resize a line to make it `cols' columns wide.
|
* Resize a line to make it `cols' columns wide.
|
||||||
@ -302,6 +307,7 @@ static void power_on(void)
|
|||||||
blink_is_real = cfg.blinktext;
|
blink_is_real = cfg.blinktext;
|
||||||
erase_char = ERASE_CHAR;
|
erase_char = ERASE_CHAR;
|
||||||
alt_which = 0;
|
alt_which = 0;
|
||||||
|
term_print_finish();
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
@ -352,8 +358,9 @@ void term_pwron(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* When the user reconfigures us, we need to check the forbidden-
|
* When the user reconfigures us, we need to check the forbidden-
|
||||||
* alternate-screen config option, and also disable raw mouse mode
|
* alternate-screen config option, disable raw mouse mode if the
|
||||||
* if the user has disabled mouse reporting.
|
* user has disabled mouse reporting, and abandon a print job if
|
||||||
|
* the user has disabled printing.
|
||||||
*/
|
*/
|
||||||
void term_reconfig(void)
|
void term_reconfig(void)
|
||||||
{
|
{
|
||||||
@ -368,6 +375,9 @@ void term_reconfig(void)
|
|||||||
sco_acs = alt_sco_acs = 0;
|
sco_acs = alt_sco_acs = 0;
|
||||||
utf = 0;
|
utf = 0;
|
||||||
}
|
}
|
||||||
|
if (!*cfg.printer) {
|
||||||
|
term_print_finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1007,6 +1017,50 @@ static void do_osc(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ANSI printing routines.
|
||||||
|
*/
|
||||||
|
static void term_print_setup(void)
|
||||||
|
{
|
||||||
|
bufchain_clear(&printer_buf);
|
||||||
|
print_job = printer_start_job(cfg.printer);
|
||||||
|
}
|
||||||
|
static void term_print_flush(void)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
int len;
|
||||||
|
int size;
|
||||||
|
while ((size = bufchain_size(&printer_buf)) > 5) {
|
||||||
|
bufchain_prefix(&printer_buf, &data, &len);
|
||||||
|
if (len > size-5)
|
||||||
|
len = size-5;
|
||||||
|
printer_job_data(print_job, data, len);
|
||||||
|
bufchain_consume(&printer_buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void term_print_finish(void)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
int len, size;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
term_print_flush();
|
||||||
|
while ((size = bufchain_size(&printer_buf)) > 0) {
|
||||||
|
bufchain_prefix(&printer_buf, &data, &len);
|
||||||
|
c = *(char *)data;
|
||||||
|
if (c == '\033' || c == '\233') {
|
||||||
|
bufchain_consume(&printer_buf, size);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
printer_job_data(print_job, &c, 1);
|
||||||
|
bufchain_consume(&printer_buf, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printer_finish_job(print_job);
|
||||||
|
print_job = NULL;
|
||||||
|
printing = only_printing = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove everything currently in `inbuf' and stick it up on the
|
* Remove everything currently in `inbuf' and stick it up on the
|
||||||
* in-memory display. There's a big state machine in here to
|
* in-memory display. There's a big state machine in here to
|
||||||
@ -1051,6 +1105,40 @@ void term_out(void)
|
|||||||
* of i18n.
|
* of i18n.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're printing, add the character to the printer
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
if (printing) {
|
||||||
|
char cc = c;
|
||||||
|
bufchain_add(&printer_buf, &c, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're in print-only mode, we use a much simpler
|
||||||
|
* state machine designed only to recognise the ESC[4i
|
||||||
|
* termination sequence.
|
||||||
|
*/
|
||||||
|
if (only_printing) {
|
||||||
|
if (c == '\033')
|
||||||
|
print_state = 1;
|
||||||
|
else if (c == (unsigned char)'\233')
|
||||||
|
print_state = 2;
|
||||||
|
else if (c == '[' && print_state == 1)
|
||||||
|
print_state = 2;
|
||||||
|
else if (c == '4' && print_state == 2)
|
||||||
|
print_state = 3;
|
||||||
|
else if (c == 'i' && print_state == 3)
|
||||||
|
print_state = 4;
|
||||||
|
else
|
||||||
|
print_state = 0;
|
||||||
|
if (print_state == 4) {
|
||||||
|
printing = only_printing = FALSE;
|
||||||
|
term_print_finish();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* First see about all those translations. */
|
/* First see about all those translations. */
|
||||||
if (termstate == TOPLEVEL) {
|
if (termstate == TOPLEVEL) {
|
||||||
if (in_utf)
|
if (in_utf)
|
||||||
@ -1815,6 +1903,24 @@ void term_out(void)
|
|||||||
toggle_mode(esc_args[i], esc_query, TRUE);
|
toggle_mode(esc_args[i], esc_query, TRUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
case ANSI_QUE('i'):
|
||||||
|
compatibility(VT100);
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (esc_nargs != 1) break;
|
||||||
|
if (esc_args[0] == 5 && *cfg.printer) {
|
||||||
|
printing = TRUE;
|
||||||
|
only_printing = !esc_query;
|
||||||
|
print_state = 0;
|
||||||
|
term_print_setup();
|
||||||
|
} else if (esc_args[0] == 4 && printing) {
|
||||||
|
printing = FALSE;
|
||||||
|
only_printing = FALSE;
|
||||||
|
term_print_finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'l': /* toggle modes to low */
|
case 'l': /* toggle modes to low */
|
||||||
case ANSI_QUE('l'):
|
case ANSI_QUE('l'):
|
||||||
compatibility(VT100);
|
compatibility(VT100);
|
||||||
@ -2657,6 +2763,8 @@ void term_out(void)
|
|||||||
check_selection(curs, cursplus);
|
check_selection(curs, cursplus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
term_print_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
46
windlg.c
46
windlg.c
@ -27,6 +27,8 @@ static int requested_help;
|
|||||||
|
|
||||||
static struct prefslist cipherlist;
|
static struct prefslist cipherlist;
|
||||||
|
|
||||||
|
#define PRINTER_DISABLED_STRING "None (printing disabled)"
|
||||||
|
|
||||||
void force_normal(HWND hwnd)
|
void force_normal(HWND hwnd)
|
||||||
{
|
{
|
||||||
static int recurse = 0;
|
static int recurse = 0;
|
||||||
@ -307,6 +309,7 @@ enum { IDCX_ABOUT =
|
|||||||
IDC_TITLE_TERMINAL,
|
IDC_TITLE_TERMINAL,
|
||||||
IDC_BOX_TERMINAL1,
|
IDC_BOX_TERMINAL1,
|
||||||
IDC_BOX_TERMINAL2,
|
IDC_BOX_TERMINAL2,
|
||||||
|
IDC_BOX_TERMINAL3,
|
||||||
IDC_WRAPMODE,
|
IDC_WRAPMODE,
|
||||||
IDC_DECOM,
|
IDC_DECOM,
|
||||||
IDC_LFHASCR,
|
IDC_LFHASCR,
|
||||||
@ -322,6 +325,8 @@ enum { IDCX_ABOUT =
|
|||||||
IDC_EDITBACKEND,
|
IDC_EDITBACKEND,
|
||||||
IDC_EDITYES,
|
IDC_EDITYES,
|
||||||
IDC_EDITNO,
|
IDC_EDITNO,
|
||||||
|
IDC_PRINTERSTATIC,
|
||||||
|
IDC_PRINTER,
|
||||||
terminalpanelend,
|
terminalpanelend,
|
||||||
|
|
||||||
featurespanelstart,
|
featurespanelstart,
|
||||||
@ -724,6 +729,9 @@ char *help_context_cmd(int id)
|
|||||||
case IDC_EDITYES:
|
case IDC_EDITYES:
|
||||||
case IDC_EDITNO:
|
case IDC_EDITNO:
|
||||||
return "JI(`',`terminal.localedit')";
|
return "JI(`',`terminal.localedit')";
|
||||||
|
case IDC_PRINTERSTATIC:
|
||||||
|
case IDC_PRINTER:
|
||||||
|
return "JI(`',`terminal.printing')";
|
||||||
|
|
||||||
case IDC_BELLSTATIC:
|
case IDC_BELLSTATIC:
|
||||||
case IDC_BELL_DISABLED:
|
case IDC_BELL_DISABLED:
|
||||||
@ -1204,6 +1212,24 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
|
|||||||
SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
|
SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int i, nprinters;
|
||||||
|
printer_enum *pe;
|
||||||
|
pe = printer_start_enum(&nprinters);
|
||||||
|
strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
|
||||||
|
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_RESETCONTENT, 0, 0);
|
||||||
|
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
|
||||||
|
0, (LPARAM) PRINTER_DISABLED_STRING);
|
||||||
|
for (i = 0; i < nprinters; i++) {
|
||||||
|
char *printer_name = printer_get_name(pe, i);
|
||||||
|
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_ADDSTRING,
|
||||||
|
0, (LPARAM) printer_name);
|
||||||
|
}
|
||||||
|
printer_finish_enum(pe);
|
||||||
|
SetDlgItemText(hwnd, IDC_PRINTER,
|
||||||
|
*cfg.printer ? cfg.printer : PRINTER_DISABLED_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
|
CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
|
||||||
cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
|
cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
|
||||||
cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
|
cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
|
||||||
@ -1330,7 +1356,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (panel == terminalpanelstart) {
|
if (panel == terminalpanelstart) {
|
||||||
/* The Terminal panel. Accelerators used: [acgoh] wdren lts */
|
/* The Terminal panel. Accelerators used: [acgoh] wdren lts p */
|
||||||
struct ctlpos cp;
|
struct ctlpos cp;
|
||||||
ctlposinit(&cp, hwnd, 80, 3, 13);
|
ctlposinit(&cp, hwnd, 80, 3, 13);
|
||||||
bartitle(&cp, "Options controlling the terminal emulation",
|
bartitle(&cp, "Options controlling the terminal emulation",
|
||||||
@ -1354,6 +1380,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
|
|||||||
"Auto", IDC_EDITBACKEND,
|
"Auto", IDC_EDITBACKEND,
|
||||||
"Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
|
"Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
|
||||||
endbox(&cp);
|
endbox(&cp);
|
||||||
|
|
||||||
|
beginbox(&cp, "Remote-controlled printing", IDC_BOX_TERMINAL3);
|
||||||
|
combobox(&cp, "&Printer to send ANSI printer output to:",
|
||||||
|
IDC_PRINTERSTATIC, IDC_PRINTER);
|
||||||
|
endbox(&cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panel == featurespanelstart) {
|
if (panel == featurespanelstart) {
|
||||||
@ -3109,6 +3140,19 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
|
|||||||
SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
|
SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDC_PRINTER:
|
||||||
|
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||||
|
int index = SendDlgItemMessage(hwnd, IDC_PRINTER,
|
||||||
|
CB_GETCURSEL, 0, 0);
|
||||||
|
SendDlgItemMessage(hwnd, IDC_PRINTER, CB_GETLBTEXT,
|
||||||
|
index, (LPARAM)cfg.printer);
|
||||||
|
} else if (HIWORD(wParam) == CBN_EDITCHANGE) {
|
||||||
|
GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer,
|
||||||
|
sizeof(cfg.printer) - 1);
|
||||||
|
}
|
||||||
|
if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING))
|
||||||
|
*cfg.printer = '\0';
|
||||||
|
break;
|
||||||
case IDC_CAPSLOCKCYR:
|
case IDC_CAPSLOCKCYR:
|
||||||
if (HIWORD(wParam) == BN_CLICKED ||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
HIWORD(wParam) == BN_DOUBLECLICKED) {
|
HIWORD(wParam) == BN_DOUBLECLICKED) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user