Commit d1735c61 authored by Alexandre Julliard's avatar Alexandre Julliard

Removed old resource compiler.

parent 87a2f8df
Makefile
lex.yy.c
winerc
y.tab.c
y.tab.h
DEFS = -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ..
SRCDIR = @srcdir@
VPATH = @srcdir@
PROGRAMS = winerc@PROGEXT@
MODULE = none
C_SRCS = winerc.c
EXTRA_SRCS = parser.y parser.l
EXTRA_OBJS = y.tab.o lex.yy.o
all: $(PROGRAMS)
depend:: y.tab.h
@MAKE_RULES@
$(PROGRAMS): $(OBJS)
$(CC) $(CFLAGS) -o winerc@PROGEXT@ $(OBJS) $(LEXLIB)
y.tab.c y.tab.h: parser.y
$(YACC) -d -t $(SRCDIR)/parser.y
lex.yy.c: parser.l
$(LEX) -8 -I $(SRCDIR)/parser.l
### Dependencies:
This is winerc, the resource compiler for the Wine project. It takes the
same input as rc.exe, but generates C files as output. These C files can
be linked together with the application, which can access the resource
data directly instead of using FindResource/LoadResource/LockResource.
The generated C code contains arrays, which represent the resource as if
it was obtained from LoadResource. A table to map resource names to
pointers is also available.
Primary applications are the resources of sysres.dll and a future
commdlg.dll, but the use in the library version is possible as well.
The expected advantage of using winerc over sysres.dll is a speed
improvement, however, actual data to support that claim are not
available. The use of winerc might also simplify the source code. For
example, the system menu is managed in the function CopySysMenu
(controls/menu.c). A winerc-based implementation would just call
return LoadMenuIndirect(_Sysres_SYSMENU);
As the resources are already in the Wine image, they are loaded on
demand as any other part of a Unix executable image.
Current State
This is the first release of winerc. It is alpha software, as the rest
of Wine is. If you use it for replacing sysres.dll, or if you write
other parts of Wine which require resource (like commdlg), you will
probably notice a loss in stability. This is especially true for cursor
and icon resources, as they are unlikely to work at all. See the TODO
file for details.
Copying
The license for Wine applies for winerc as well. Read the files LICENSE
and WARRANTY in the current or any future distribution for details. You
can change any source files, and you can add your own copyright notice,
as long as you leave the existing copyrights intact.
Bug Reports and Fixes
If you find a bug in winerc, you can report it to me,
martin@cs.csufresno.edu (Martin von Loewis) or to
comp.emulators.ms-windows.wine. If you can fix the bug, send the diffs
and ChangeLog entry to julliard@lrc.epfl.ch (Alexandre Julliard).
This release of winerc contains a resource script for sysres.dll,
obtained by saving it as RC in Borland's Resource Workshop. Obsolete
or duplicate resources where removed. If you find that I deleted to
little or to much, drop me a note.
You are encouraged to create sysres dumps using your favoured resource
editor. If the output cannot be compiled, or the generated C code is
different from mine, report this as a bug. When comparing the results,
note that only the order might be different, which is not considered a
bug.
systest.c is a Windows program which shows how to use winerc generated
resources. Compile it with your Windows compiler, and link it with
sysres.c. It also shows how to prevent curious people from spying your
bitmaps, dialogs, and menus :-)
Deleted resources:
Bitmap: OBMCLOSE
Menu: 1, 0xF140+2
Dialog: 0XF140+3, EXCLAMATION_MSGBOX, QUESTION_MSGBOX, STOP_MSGBOX
Icon: SYSIDI_STOPICON
1. User interface
- use GNU's long_getopt
- allow to pass input and output files via command line
- add options for various not-yet-implemented features (Unicode, Win32
format, non-native/native alignment and endianness, compact output
format)
2. Input format
- improve input file processing
Currently, certain pre- and postprocessing is required. winerc
should accept an arbitrary resource script and generate the C file
with as little intermediate files as possible. I'm not sure how to
handle the symbols from windows.h. There are certain options:
* winerc predefines the symbols via the cpp command line
* windows.h is #include'd, and the resulting C code is dropped
(Should winerc do C parsing here?)
* a stripped-down version of windows.h is included,
generated by "grep '^#' windows.h"
* windows.h #ifdef's every C code with _RC_INVOKED
(commercial solution)
- complete input syntax
The goal here is to support every existing resource file which is
accepted by another resource compiler, not to put as much fancy
features into the compiler as possible. Every correct resource file
which generates a parse error can be reported as a bug, a problem
analysis and a fix would be appreciated.
3. Output file format
- add missing resources (fonts, versioninfo, stringtables,rcdata)
- check style handling
The semantics of control and dialog styles is somewhat poorly
documented. For example, I couldn't find a reference that every
control has the WS_VISIBLE and WS_CHILD style, even if they are
not specified. What other styles are considered default?
The existance of default styles implies support for disabling these,
unlike any other proper programming language,
NOT WS_VISIBLE | WS_GROUP
does *not* mean ~WS_VISIBLE, but WS_CHILD|WS_GROUP (in C semantics).
What other strange semantics are there?
- check cursor and icon handling
At the moment, the .CUR and .ICO files are copied byte-by-byte into
the C array. This is probably wrong, as there are things like cursor
and icon groups. In which way should they be present in a Wine image?
Should we have arrays for every cursor, as well as the cursor group?
Is one cursor per group enough, in the context of X? If so, do we
still need the group?
- create a more compact output file
The current format is well-suited for debugging, as one can easily
match it with a resource' hex dump. A more compact format would use
strings instead of integer lists. A clever algorithm for embedding
values <32 and >127 is required.
- platform independence
Currently, the lay-out of the resources is just as it is in Win3.1 -
packed structures, little endian. Although this format can be used
on any architecture, aligned data and native endianness would speed-up
the resource manipulation and simplify the code. OTOH, this would
break applications that rely on the lay-out. All this is of interest
for the library version only.
- Win32 support
4. Programming Style
- memory management
No memory is freed in the current implementation.
/*
*
* Copyright Martin von Loewis, 1994
*
*/
/* resource types */
enum rt {acc,bmp,cur,dlg,fnt,ico,men,rdt,str};
/* generic resource
Bytes can be inserted at arbitrary positions, the data field (res)
grows as required. As the dialog header contains the number of
controls, this number is generated in num_entries. If n_type if 0,
the resource name is i_name, and s_name otherwise. Top level
resources are linked via next. All gen_res objects are linked via
g_prev, g_next for debugging purposes. space is the length of res,
size is the used part of res.
As most bison rules are right recursive, new items are usually
inserted at the beginning
*/
typedef struct gen_res{
int size,space;
int num_entries;
enum rt type;
union{
int i_name;
char* s_name;
}n;
int n_type; /*0 - integer, 1 = string*/
struct gen_res *next;
struct gen_res *g_prev,*g_next;
unsigned char res[0];
} gen_res;
/* control/dialog style. or collects styles, and collects NOT styles */
typedef struct rc_style{
int and, or;
}rc_style;
/* create a new resource */
gen_res *new_res(void);
/* double the space of the resource */
gen_res* grow(gen_res*);
/* insert byte array at the beginning, increase count */
gen_res* insert_at_beginning(gen_res*,char*,int);
/* insert byte array at offset */
gen_res* insert_bytes(gen_res*,char*,int,int);
/* delete bytes at offset */
gen_res* delete_bytes(gen_res*,int,int);
/* create a new style */
rc_style* new_style(void);
/* convert \t to tab etc. */
char* parse_c_string(char*);
/* get the resources type, convert dlg to "DIALOG" and so on */
char* get_typename(gen_res*);
gen_res* add_accelerator(int,int,int,gen_res*);
gen_res* add_string_accelerator(char*,int,int,gen_res*);
gen_res* add_ascii_accelerator(int,int,int,gen_res*);
gen_res* add_vk_accelerator(int,int,int,gen_res*);
gen_res* new_dialog(void);
gen_res* dialog_style(rc_style*,gen_res*);
int dialog_get_menu(gen_res*);
int dialog_get_class(gen_res*);
int dialog_get_caption(gen_res*);
int dialog_get_fontsize(gen_res*);
gen_res* dialog_caption(char*,gen_res*);
gen_res* dialog_font(short,char*,gen_res*);
gen_res* dialog_class(char*,gen_res*);
gen_res* dialog_menu_id(short,gen_res*);
gen_res* dialog_menu_str(char*,gen_res*);
gen_res* create_control_desc(int,int,int,int,int,rc_style*);
gen_res* label_control_desc(char*,gen_res*);
gen_res* create_generic_control(char*,int,char*,rc_style*,int,int,int,int);
gen_res* add_control(int,int,gen_res*,gen_res*);
gen_res* add_icon(char*,int,int,int,gen_res*,gen_res*);
gen_res* add_generic_control(gen_res*,gen_res*);
gen_res* make_dialog(gen_res*,int,int,int,int,gen_res*);
gen_res *hex_to_raw(char*,gen_res*);
gen_res *int_to_raw(int,gen_res*);
gen_res *make_font(gen_res*);
gen_res *make_raw(gen_res*);
gen_res *make_bitmap(gen_res*);
gen_res *make_icon(gen_res*);
gen_res *make_cursor(gen_res*);
gen_res *load_file(char*);
gen_res *add_menuitem(char*,int,int,gen_res*);
gen_res *add_popup(char*,short,gen_res*,gen_res*);
gen_res *make_menu(gen_res*);
gen_res *add_resource(gen_res*,gen_res*);
void add_str_tbl_elm(int,char*);
void create_output(gen_res*);
void set_out_file(char*);
#define CT_BUTTON 0x80
#define CT_EDIT 0x81
#define CT_STATIC 0x82
#define CT_LISTBOX 0x83
#define CT_SCROLLBAR 0x84
#define CT_COMBOBOX 0x85
extern int verbose;
/* -*-C-*-
*
* Copyright Martin von Loewis, 1994
*
*/
%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "y.tab.h"
#define YY_NO_UNPUT
int line_number=1;
%}
%%
ACCELERATORS return ACCELERATORS;
ALT return ALT;
ASCII return ASCII;
BEGIN return tBEGIN;
BITMAP return tBITMAP;
CAPTION return CAPTION;
CHECKBOX return CHECKBOX;
CHECKED return CHECKED;
CLASS return CLASS;
COMBOBOX return COMBOBOX;
CONTROL return CONTROL;
CTEXT return CTEXT;
CURSOR return CURSOR;
DEFPUSHBUTTON return DEFPUSHBUTTON;
DIALOG return DIALOG;
DISCARDABLE return DISCARDABLE;
EDITTEXT return EDITTEXT;
END return tEND;
FIXED return tFIXED;
FONT return FONT;
GRAYED return GRAYED;
GROUPBOX return GROUPBOX;
HELP return HELP;
ICON return ICON;
INACTIVE return INACTIVE;
LISTBOX return LISTBOX;
LTEXT return LTEXT;
MENU return MENU;
MENUBARBREAK return MENUBARBREAK;
MENUBREAK return MENUBREAK;
MENUITEM return MENUITEM;
MOVEABLE return MOVEABLE;
LOADONCALL return LOADONCALL;
NOINVERT return NOINVERT;
NOT return NOT;
NUMBER return NUMBER;
POPUP return POPUP;
PRELOAD return PRELOAD;
PUSHBUTTON return PUSHBUTTON;
PURE return PURE;
RADIOBUTTON return RADIOBUTTON;
RCDATA return RCDATA;
RTEXT return RTEXT;
SCROLLBAR return SCROLLBAR;
SHIFT return SHIFT;
SEPARATOR return SEPARATOR;
STRING return tSTRING;
STRINGTABLE return STRINGTABLE;
STYLE return STYLE;
VERSIONINFO return VERSIONINFO;
VIRTKEY return VIRTKEY;
\{ return tBEGIN;
\} return tEND;
[+-]?[0-9]+ yylval.num=atoi(yytext);return NUMBER;
0x[0-9A-Fa-f]+L? yylval.num=strtoul(yytext,0,16);return NUMBER;
[A-Za-z][A-Za-z_0-9]* yylval.str=strdup(yytext);return IDENT;
\"[^"]*\" yylval.str=parse_c_string(yytext);return tSTRING;
\'[^']*\' yylval.str=strdup(yytext+1);return SINGLE_QUOTED;
\n { line_number++; }
[ \t\r] ;
. return yytext[0];
%%
#ifndef yywrap
int yywrap(void) { return 1; }
#endif
%{
/*
*
* Copyright Martin von Loewis, 1994
*/
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "windows.h"
int yylex(void);
int yyerror(const char *s);
%}
%union{
gen_res *res;
char *str;
int num;
struct rc_style *style;
}
%token <num> NUMBER
%token <str> tSTRING SINGLE_QUOTED IDENT
%token ACCELERATORS ALT ASCII tBEGIN tBITMAP CAPTION CHECKBOX CHECKED
%token CLASS COMBOBOX CONTROL CTEXT CURSOR DEFPUSHBUTTON DIALOG
%token DISCARDABLE EDITTEXT tEND tFIXED FONT GRAYED GROUPBOX HELP ICON
%token IDENT INACTIVE LISTBOX LTEXT MENU MENUBARBREAK MENUBREAK MENUITEM
%token MOVEABLE LOADONCALL NOINVERT NOT NOT_SUPPORTED POPUP PRELOAD
%token PURE PUSHBUTTON RADIOBUTTON RCDATA RTEXT SCROLLBAR SHIFT SEPARATOR
%token SINGLE_QUOTED tSTRING STRINGTABLE STYLE VERSIONINFO VIRTKEY
%type <res> resource_file resource resources resource_definition accelerators
%type <res> events bitmap cursor dialog dlg_attributes controls
%type <res> generic_control labeled_control control_desc font icon
%type <res> iconinfo menu menu_body item_definitions rcdata raw_data raw_elements
%type <res> stringtable strings versioninfo
%type <num> acc_options item_options
%type <style> style style_elm optional_style
%%
resource_file: resources {create_output($1);}
/*resources are put into a linked list*/
resources: {$$=0;}
|resource resources {$$=add_resource($1,$2);}
;
/* get the name for a single resource*/
resource: NUMBER resource_definition
{$$=$2;$$->n.i_name=$1;$$->n_type=0;
if(verbose)fprintf(stderr,"Got %s %d\n",get_typename($2),$1);
}
| IDENT resource_definition
{$$=$2;$$->n.s_name=$1;$$->n_type=1;
if(verbose)fprintf(stderr,"Got %s %s\n",get_typename($2),$1);
}
| stringtable
{$$=$1; /* <-- should be NULL */
if(verbose)fprintf(stderr,"Got STRINGTABLE\n");
}
;
/* get the value for a single resource*/
resource_definition: accelerators {$$=$1;}
| bitmap {$$=$1;}
| cursor {$$=$1;}
| dialog {$$=$1;}
| font {$$=$1;}
| icon {$$=$1;}
| menu {$$=$1;}
| rcdata {$$=$1;}
| versioninfo {$$=$1;}
;
/* have to use tBEGIN because BEGIN is predefined */
accelerators: ACCELERATORS load_and_memoption tBEGIN events tEND {$$=$4;$$->type=acc;}
/* the events are collected in a gen_res, as the accelerator resource is just
an array of events */
events: {$$=new_res();}
| tSTRING ',' NUMBER acc_options events
{$$=add_string_accelerator($1,$3,$4,$5);}
| NUMBER ',' NUMBER ',' ASCII acc_options events
{$$=add_ascii_accelerator($1,$3,$6,$7);}
| NUMBER ',' NUMBER ',' VIRTKEY acc_options events
{$$=add_vk_accelerator($1,$3,$6,$7);}
acc_options: {$$=0;}
| ',' NOINVERT acc_options {$$=$3|2;}
| ',' ALT acc_options {$$=$3|16;}
| ',' SHIFT acc_options {$$=$3|4;}
| ',' CONTROL acc_options {$$=$3|8;}
bitmap: tBITMAP load_and_memoption tSTRING {$$=make_bitmap(load_file($3));}
| tBITMAP load_and_memoption raw_data {$$=make_bitmap($3);}
/* load and memory options are ignored */
load_and_memoption: | lamo load_and_memoption
lamo: PRELOAD | LOADONCALL | tFIXED | MOVEABLE | DISCARDABLE | PURE
cursor: CURSOR load_and_memoption tSTRING {$$=make_cursor(load_file($3));}
|CURSOR load_and_memoption raw_data {$$=make_cursor($3);}
dialog: DIALOG load_and_memoption NUMBER ',' NUMBER ',' NUMBER ',' NUMBER
dlg_attributes
tBEGIN controls tEND
{$$=make_dialog($10,$3,$5,$7,$9,$12);}
dlg_attributes: {$$=new_dialog();}
| STYLE style dlg_attributes
{$$=dialog_style($2,$3);}
| CAPTION tSTRING dlg_attributes
{$$=dialog_caption($2,$3);}
| FONT NUMBER ',' tSTRING dlg_attributes
{$$=dialog_font($2,$4,$5);}
| CLASS tSTRING dlg_attributes
{$$=dialog_class($2,$3);}
| MENU tSTRING dlg_attributes
{$$=dialog_menu_str($2,$3);}
| MENU NUMBER dlg_attributes
{$$=dialog_menu_id($2,$3);}
/* the controls are collected into a gen_res, and finally the dialog header
is put at the beginning */
controls: {$$=new_res();}
| CHECKBOX labeled_control controls
{$$=add_control(CT_BUTTON, BS_CHECKBOX, $2, $3);}
| COMBOBOX control_desc controls
{$$=add_control(CT_COMBOBOX, 0, $2, $3);}
| CONTROL generic_control controls
{$$=add_generic_control($2, $3);}
| CTEXT labeled_control controls
{$$=add_control(CT_STATIC, SS_CENTER, $2, $3);}
| DEFPUSHBUTTON labeled_control controls
{$$=add_control(CT_BUTTON, BS_DEFPUSHBUTTON, $2, $3);}
| EDITTEXT control_desc controls
{$$=add_control(CT_EDIT, 0, $2, $3);}
| GROUPBOX labeled_control controls
{$$=add_control(CT_BUTTON, BS_GROUPBOX, $2, $3);}
/*special treatment for icons, as the extent is optional*/
| ICON tSTRING ',' NUMBER ',' NUMBER ',' NUMBER iconinfo controls
{$$=add_icon($2, $4, $6, $8, $9, $10);}
| LISTBOX control_desc controls
{$$=add_control(CT_LISTBOX, 0, $2, $3);}
| LTEXT labeled_control controls
{$$=add_control(CT_STATIC, SS_LEFT, $2, $3);}
| PUSHBUTTON labeled_control controls
{$$=add_control(CT_BUTTON, BS_PUSHBUTTON, $2, $3);}
| RADIOBUTTON labeled_control controls
{$$=add_control(CT_BUTTON, BS_RADIOBUTTON, $2, $3);}
| RTEXT labeled_control controls
{$$=add_control(CT_STATIC, SS_RIGHT, $2, $3);}
| SCROLLBAR control_desc controls
{$$=add_control(CT_SCROLLBAR, 0, $2, $3);}
labeled_control: tSTRING ',' control_desc {$$=label_control_desc($1,$3);}
control_desc: NUMBER ',' NUMBER ',' NUMBER ',' NUMBER ',' NUMBER optional_style
{$$=create_control_desc($1,$3,$5,$7,$9,$10);}
optional_style: {$$=0;}|
',' style {$$=$2;}
iconinfo: /*set extent and style to 0 if they are not provided */
{$$=create_control_desc(0,0,0,0,0,0);}
/* x and y are overwritten later */
| ',' NUMBER ',' NUMBER optional_style
{$$=create_control_desc(0,0,0,$2,$4,$5);}
generic_control: tSTRING ',' NUMBER ',' tSTRING ',' style ',' NUMBER
',' NUMBER ',' NUMBER ',' NUMBER
{$$=create_generic_control($1,$3,$5,$7,$9,$11,$13,$15);}
font: FONT load_and_memoption tSTRING {$$=make_font(load_file($3));}
icon: ICON load_and_memoption tSTRING {$$=make_icon(load_file($3));}
| ICON load_and_memoption raw_data {$$=make_icon($3);}
menu: MENU load_and_memoption menu_body {$$=make_menu($3);}
/* menu items are collected in a gen_res and prefixed with the menu header*/
menu_body: tBEGIN item_definitions tEND {$$=$2;}
item_definitions: {$$=new_res();}
| MENUITEM tSTRING ',' NUMBER item_options item_definitions
{$$=add_menuitem($2,$4,$5,$6);}
| MENUITEM SEPARATOR item_definitions
{$$=add_menuitem("",0,0,$3);}
| POPUP tSTRING item_options menu_body item_definitions
{$$=add_popup($2,$3,$4,$5);}
item_options: {$$=0;}
| ',' CHECKED item_options {$$=$3|MF_CHECKED;}
| ',' GRAYED item_options {$$=$3|MF_GRAYED;}
| ',' HELP item_options {$$=$3|MF_HELP;}
| ',' INACTIVE item_options {$$=$3|MF_DISABLED;}
| ',' MENUBARBREAK item_options {$$=$3|MF_MENUBARBREAK;}
| ',' MENUBREAK item_options {$$=$3|MF_MENUBREAK;}
rcdata: RCDATA load_and_memoption raw_data {$$=make_raw($3);}
raw_data: tBEGIN raw_elements tEND {$$=$2;}
raw_elements: SINGLE_QUOTED {$$=hex_to_raw($1,new_res());}
| NUMBER {$$=int_to_raw($1,new_res());}
| SINGLE_QUOTED raw_elements {$$=hex_to_raw($1,$2);}
| NUMBER ',' raw_elements {$$=int_to_raw($1,$3);}
stringtable: STRINGTABLE load_and_memoption tBEGIN strings tEND
{$$=$4;}
strings: {$$=0;}|
NUMBER tSTRING strings {$$=0;add_str_tbl_elm($1,$2);}
versioninfo: VERSIONINFO NOT_SUPPORTED {$$=0;}
/* NOT x | NOT y | a | b means (a|b)& ~x & ~y
NOT is used to disable default styles */
style: {$$=new_style();}
| style_elm {$$=$1;}
| style_elm '|' style
{$$=$1;$$->or|=$3->or;$$->and&=$3->and;free($3);}
style_elm: NUMBER {$$=new_style();$$->or=$1;}
| NOT NUMBER {$$=new_style();$$->and=~($2);}
| '(' style ')' {$$=$2;}
%%
extern int line_number;
extern char* yytext;
int yyerror( const char *s )
{
fprintf(stderr,"stdin:%d: %s before '%s'\n",line_number,s,yytext);
return 0;
}
#include <windows.h>
LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
BOOL CALLBACK _export DlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
HINSTANCE hInst;
HMENU hMenu,dummy;
extern char sysres_MENU_SYSMENU[],sysres_BITMAP_WINELOGO[],sysres_DIALOG_2[];
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int cmdShow)
{
MSG msg;
WNDCLASS wcHdumpClass;
HWND hWndMain;
hInst=hInstance;
/* Define the window class for this application. */
wcHdumpClass.lpszClassName = "WrcTestClass";
wcHdumpClass.hInstance = hInstance;
wcHdumpClass.lpfnWndProc = WndProc;
wcHdumpClass.hCursor = 0;
wcHdumpClass.hIcon = 0;
wcHdumpClass.lpszMenuName = 0;
wcHdumpClass.hbrBackground = GetStockObject(WHITE_BRUSH);
wcHdumpClass.style = CS_HREDRAW | CS_VREDRAW;
wcHdumpClass.cbClsExtra = 0;
wcHdumpClass.cbWndExtra = 0;
RegisterClass(&wcHdumpClass);
hWndMain = CreateWindow("WrcTestClass","WrcTest",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x window location */
CW_USEDEFAULT, /* y */
CW_USEDEFAULT, /* cx and size */
CW_USEDEFAULT, /* cy */
NULL, /* no parent for this window */
NULL, /* use the class menu */
hInstance, /* who created this window */
NULL /* no parms to pass on */
);
ShowWindow(hWndMain,SW_SHOW);
UpdateWindow(hWndMain);
hMenu=LoadMenuIndirect(sysres_MENU_SYSMENU);
/* see Q75254 on how to create a popup menu via LoadMenuIndirect */
dummy=CreateMenu();
InsertMenu(dummy,0,MF_POPUP,hMenu,NULL);
hMenu=GetSubMenu(dummy,0);
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
POINT ptCurrent;
switch(message)
{
case WM_LBUTTONDOWN:
ptCurrent=MAKEPOINT(lParam);
ClientToScreen(hWnd,&ptCurrent);
TrackPopupMenu(hMenu,0,ptCurrent.x,ptCurrent.y,0,hWnd,0);
break;
case WM_PAINT:
{ PAINTSTRUCT ps;
BITMAPINFO *bm=sysres_BITMAP_WINELOGO;
char *bits=bm;
bits+=bm->bmiHeader.biSize;
bits+=(1<<bm->bmiHeader.biBitCount)*sizeof(RGBQUAD);
BeginPaint(hWnd,&ps);
SetDIBitsToDevice(ps.hdc,0,0,bm->bmiHeader.biWidth,
bm->bmiHeader.biHeight,0,0,0,bm->bmiHeader.biHeight,
bits,bm,DIB_RGB_COLORS);
EndPaint(hWnd,&ps);
break;
}
case WM_COMMAND:
CreateDialogIndirect(hInst,sysres_DIALOG_2,hWnd,DlgProc);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0L;
}
BOOL CALLBACK _export DlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
return 1;
case WM_COMMAND:
DestroyWindow(hWnd);
return 0;
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment