C++ 21点算法
21点游戏的一般算法是什么? 我在C++中写了一篇,最后用了太多的if语句来破坏整个事情。< /P> 该项目是一个win32 GUI应用程序,Im发布消息循环以及检查游戏状态的程序部分 发布完整的代码将使其变得庞大,因此以下是指向所有文件的链接: 消息循环C++ 21点算法,c++,algorithm,blackjack,C++,Algorithm,Blackjack,21点游戏的一般算法是什么? 我在C++中写了一篇,最后用了太多的if语句来破坏整个事情。< /P> 该项目是一个win32 GUI应用程序,Im发布消息循环以及检查游戏状态的程序部分 发布完整的代码将使其变得庞大,因此以下是指向所有文件的链接: 消息循环 LRESULT回调WndProc(HWND HWND,UINT Msg,WPARAM WPARAM,LPARAM LPARAM){ 开关(Msg) { 案例WM_油漆: { PAINTSTRUCT-PS; HDC HDC=开始喷漆(hWnd
LRESULT回调WndProc(HWND HWND,UINT Msg,WPARAM WPARAM,LPARAM LPARAM){
开关(Msg)
{
案例WM_油漆:
{
PAINTSTRUCT-PS;
HDC HDC=开始喷漆(hWnd和PS);
You.Draw(hDC);
经销商提款(hDC);
端漆(hWnd和PS);
如果(已启用下注){
Bet.GetFocus();
Bet.Select(0,Bet.Length());
}
}
返回0;
案例WM_CTLORSTATIC:
{
SetBkMode((HDC)wParam,透明);
}
返回(INT_PTR)(HBRUSH)GetStockObject(NULL_);
案例WM_创建:
{
//创建编辑控件
创建(hWnd,10550100,25,“0”);
//创建标签
字符缓冲区[30];
sprintf(缓冲区,“%d”,You.HandValue());
创建(hWnd,10500100,40,“输入下注金额”);
创建(hWnd,1037510040,“游戏控件”);
创建(hWnd,10,10,100,20,“你:”);
PlayerLabels.Create(hWnd,1015010020,“经销商:”);
创建(hWnd,(int)You.x[You.cards]+85,(int)You.y[You.cards]+25100,20,Buffer);
创建(hWnd,125500,100,40,“你的钱:”);
sprintf(缓冲区,“%d”,你的钱);
创建(hWnd,125525100,40,缓冲区);
//创建按钮
创建(hWnd,10600100,50,“Ok”);
创建(hWnd,10425100,50,“命中”);
创建(hWnd,12042510050,“支架”);
//选择文本
选择(0,3);
}
返回0;
案例WM_结束:
出口(0);
打破
case WM_命令:
{
开关(HIWORD(wParam))
{
案件编号:
{
开关(LOWORD(wParam))
{
案件编号(正常):
{
//下注
int-bet=0;
bet=StringToNumber(bet.Text());
你,钱-=打赌;
字符缓冲区[30];
sprintf(缓冲区,“%d”,你的钱);
MoneyValue.SetText(缓冲区);
//更新窗口
无效(hWnd,0,真);
You.Bet=是;
好的,禁用();
Bet.Disable();
You.DealCard();
You.DealCard();
Dealer.DealCard();
Dealer.DealCard();
You.win=false;
You.bust=false;
You.playing=是;
Dealer.win=否;
Dealer.bust=否;
Dealer.playing=是;
}
打破
案件编号(HIT):
{
if(You.HandValue()<21&&You.playing&&You.bust){
//如果玩家没有赢或输,就给他发一张牌
You.DealCard();
}
if((Dealer.HandValue()作为第一步:我可能不会混合游戏逻辑和GUI逻辑。将它们分为不同的模块
如果你只有两个玩家,你只需要一个bool就可以决定哪一个赢了。你不需要两个玩家的Bust和wind变量。一个关于21点算法的谷歌搜索。我相信如果你用谷歌做更多的研究,你也可以找到一些东西
要了解如何计算出玩游戏需要执行的实际步骤,请在纸上计算出游戏的不同步骤,然后决定如何创建表示游戏部分的类以及这些类中的函数来执行游戏的不同步骤。”
这可能是一个迭代的过程,在这里你要经历它,然后创建一些类、函数等等,现在你可以回头看看你所做的是否有意义,改进设计等等
也许还可以玩这个游戏,看看做了什么,如何将其转化为代码。我已经修改了程序处理消息的方式,并将其作为单独的答案发布。
它仍然因为一个小故障而损坏,但我认为总体想法是可靠的。如有评论,将不胜感激
卡片
我已经被告知很多次了,不要将两者混用。但是GUI中的更改是触发游戏的因素。那么我该如何让它工作呢?你可以建立一个类似事件的系统,在这个系统中,GUI中引发的事件传播到你的逻辑类。例如,将你的游戏逻辑放在一个类中。然后调用这个类的相应方法。或者你可以使用f或者是MVC设计。我写了一些东西,但我认为完整的答案太长了,最好还是作为一个新问题来回答。最简单的答案是有一个控制游戏逻辑的模型,然后是一个GUI,它的任务是显示东西,接受用户输入,并将其传递给模型。如果有疑问,应该考虑到哪里r您的GUI旁边是一个假设的纯文本版本。如果两个版本都需要代码,则可能在模型中。如果它只需要GUI或文本中的一个,则应该只在该版本中。我已经编写了blackjack的控制台版本。它起作用了,但它充满了令人厌恶的全局变量;这些是关于如何我想要的是描述游戏如何进行的算法。在我看来并不坏。当游戏有很多规则时,你会得到很多ifs。(注意:并非所有游戏都是如此。如果你可以将规则作为状态机编写,你可以使用两个2d状态数组和按状态/动作索引的函数指针。第一个显示“下一个”状态,第二个,当采用该路径时需要执行的函数。然后,您需要的是许多具有类似原型的小函数并填写表格。我不认为这适用于21点)而且,事实证明我是在
LRESULT CALLBACK WndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ){
switch(Msg)
{
case WM_PAINT:
{
PAINTSTRUCT PS;
HDC hDC = BeginPaint(hWnd, &PS);
You.Draw(hDC);
Dealer.Draw(hDC);
EndPaint(hWnd, &PS);
if(Bet.Enabled){
Bet.GetFocus();
Bet.Select(0,Bet.Length());
}
}
return 0;
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC)wParam, TRANSPARENT);
}
return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);
case WM_CREATE:
{
//Create edit control
Bet.Create(hWnd, 10, 550, 100, 25, "0");
//Create labels
char Buffer[30];
sprintf(Buffer, "%d", You.HandValue());
BetLabel.Create(hWnd, 10, 500, 100, 40, "Enter Bet Amount");
GameControls.Create(hWnd, 10, 375, 100, 40, "Game Controls");
PlayerLabels.Create(hWnd, 10, 10, 100, 20, "You:");
PlayerLabels.Create(hWnd, 10, 150, 100, 20, "Dealer:");
HandValueLabel.Create(hWnd, (int)You.x[You.cards] + 85, (int)You.y[You.cards] + 25, 100, 20, Buffer);
YourMoney.Create(hWnd, 125, 500, 100, 40, "Your money: ");
sprintf(Buffer, "%d", You.money);
MoneyValue.Create(hWnd, 125, 525, 100, 40, Buffer);
//Create buttons
Ok.Create(hWnd, 10, 600, 100, 50, "Ok");
Hit.Create(hWnd, 10, 425, 100, 50, "Hit");
Stand.Create(hWnd, 120, 425, 100, 50, "Stand");
//Select Text
Bet.Select(0,3);
}
return 0;
case WM_CLOSE:
exit(0);
break;
case WM_COMMAND:
{
switch(HIWORD(wParam))
{
case BN_CLICKED:
{
switch(LOWORD(wParam))
{
case ID_OK:
{
//Place bet
int bet = 0;
bet = StringToNumber(Bet.Text());
You.money -= bet;
char Buffer[30];
sprintf(Buffer, "%d", You.money);
MoneyValue.SetText(Buffer);
//Update the window
InvalidateRect(hWnd, 0, TRUE);
You.Bet = YES;
Ok.Disable();
Bet.Disable();
You.DealCard();
You.DealCard();
Dealer.DealCard();
Dealer.DealCard();
You.win = false;
You.bust = false;
You.playing = YES;
Dealer.win = NO;
Dealer.bust = NO;
Dealer.playing = YES;
}
break;
case ID_HIT:
{
if(You.HandValue() < 21 && You.playing && !You.bust){
//Deal a card to the player, if he hasn't won or lost
You.DealCard();
}
if((Dealer.HandValue() <= 17 || Dealer.HandValue() < You.HandValue()) && Dealer.playing)
{
Dealer.DealCard();
}
//Update Hand Value
char Buffer[30];
sprintf(Buffer, "%d", You.HandValue());
HandValueLabel.SetText(Buffer);
InvalidateRect(hWnd,0,TRUE);
MoveWindow(HandValueLabel.Handle, (int)You.x[You.cards] + 80, (int)You.y[You.cards] + 25, 100, 20, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
}
break;
case ID_STAND:
if(Hit.Enabled){
//Don't deal more cards
Hit.Disable();
You.playing = false;
}
if((Dealer.HandValue() <= 17 || Dealer.HandValue() < You.HandValue()) && Dealer.playing){
//Deal a card to the dealer
Dealer.DealCard();
}
}
void ProcessStatus(HWND hWnd){
if(Dealer.HandValue() > 17){
if(Dealer.HandValue() > You.HandValue() && Dealer.playing){
Dealer.playing = false;
}
else if(!You.playing && Dealer.HandValue() <= You.HandValue() && Dealer.playing){
Dealer.DealCard();
}
}
else if(Dealer.HandValue() <= 17 && Dealer.HandValue() <= You.HandValue() && !You.playing && Dealer.playing){
Dealer.DealCard();
}
if(EvaluateStatus() != 0){
status = OVER;
}
if(EvaluateStatus() == -1){
switch(MessageBoxA(hWnd, "You Lost! \n Keep Playing ?", "You Lost!", MB_YESNO | MB_ICONQUESTION))
{
case IDYES:
Reset();
break;
case IDNO:
exit(0);
break;
}
}
else if(EvaluateStatus() == 1){
switch(MessageBoxA(hWnd, "You Won! \n Keep Playing ?", "You Won!", MB_YESNO | MB_ICONQUESTION))
{
case IDYES:
Reset();
break;
case IDNO:
exit(0);
break;
}
}
}
int EvaluateStatus()
{
if(You.HandValue() > 21 && You.playing)
{
You.bust = true;
Dealer.win = true;
You.playing = NO;
return -1;
}
if(You.HandValue() == 21)
{
You.win = true;
return 1;
}
if(Dealer.HandValue() > 21)
{
Dealer.bust = true;
You.win = true;
return 1;
}
if(Dealer.HandValue() == 21)
{
Dealer.win = true;
return -1;
}
if(!You.playing && Dealer.HandValue() > You.HandValue() &&!Dealer.bust)
{
Dealer.win = true;
return -1;
}
if(You.HandValue() > Dealer.HandValue() && (!You.playing && (!Dealer.playing || Dealer.bust)))
{
You.win = true;
return 1;
}
if(You.HandValue() == Dealer.HandValue() && (!You.playing || !Dealer.playing))
{
You.win = true;
return 1;
}
/*
* cards.h
*
* Created on: Aug 31, 2011
* Author: Viraj
*/
#ifndef CARDS_H_
#define CARDS_H_
#include <iostream>
#include <algorithm>
#define STARTED true
#define OVER false
#define YES true
#define NO false
using namespace std;
HINSTANCE hApplication;
HBITMAP Bitmap;
char Buffer[30];
class Deck{
public:
int deck[53];
Deck(){
for(int suit = 1; suit <= 4; suit++){
for(int card = 1; card <= 13; card++){
deck[((suit-1)*13)+card] = card;
}
}
deck[0] = 0;
}
};
Deck deck;
class Cards{
private:
int card_seed;
int suit_seed;
public:
int card[11];
int cards;
int value[11];
Cards(){
fill(card, card + 10, 0);
fill(value, value + 10, 0);
cards = 0;
}
void DealCard()
{
cards++;
while(!deck.deck[card[cards]]){
card_seed = rand()%13 + 1;
suit_seed = rand()%4 + 1;
card[cards] = (suit_seed - 1)*13 + card_seed;
}
deck.deck[card[cards]] = 0;
if(card_seed > 1 && card_seed < 11){
value[cards] = card_seed;
}
else if(card_seed >= 11 && card_seed <= 13){
value[cards] = 10;
}
else if(card_seed == 1){
value[cards] = 11;
}
}
};
class Player : public Cards {
public:
float x[11];
float y[11];
bool playing;
bool bust;
bool win;
int money;
Player(const char* Type){
srand(time(NULL));
playing = true;
if(Type == "Dealer"){
for(int card = 1; card <= 10; card++){
x[card] = 10 + (card-1)*75;
y[card] = 200;
}
}
else{
for(int card = 1; card <= 10; card++){
x[card] = 10 + (card-1)*75;
y[card] = 35;
money = 1000;
}
}
}
void Reset(){
cards = 0;
fill(card, card + 10, 0);
fill(value, value + 10, 0);
playing = true;
}
int HandValue(){
int sum = 0;
for(int current_card = 1; current_card <= cards; current_card++){
sum += value[current_card];
}
if(sum > 21){
for(int current_card = 1; current_card <= cards; current_card++){
if(value[current_card] == 11 && sum > 21){
value[current_card] = 1;
sum = HandValue();
break;
}
}
}
return sum;
}
void Draw(HDC hDC){
HDC MemoryDevice;
for(int CardToLoad = 1; CardToLoad <= cards; CardToLoad++){
Bitmap = LoadBitmap(hApplication, MAKEINTRESOURCE(card[CardToLoad]));
MemoryDevice = CreateCompatibleDC(hDC);
SelectObject(MemoryDevice, Bitmap);
BitBlt(hDC, (int)x[CardToLoad], (int)y[CardToLoad], 75, 100, MemoryDevice, 0, 0, SRCCOPY);
}
DeleteDC(MemoryDevice);
}
};
class CONTROL{
public:
HWND Handle;
char* ClassName;
char* Caption;
DWORD ClassStyle;
DWORD ExtendedStyle;
int x;
int y;
int Width;
int Height;
int ID;
bool Enabled;
void Create(HWND ParentHandle, int x, int y, int Width, int Height, char* Caption){
Handle = CreateWindowExA(ExtendedStyle, ClassName, Caption, ClassStyle, x, y, Width, Height, ParentHandle, (HMENU)ID, NULL, NULL);
Enabled = true;
CONTROL::Caption = Caption;
CONTROL::x = x;
CONTROL::y = y;
CONTROL::Width = Width;
CONTROL::Height = Height;
}
void GetFocus(){
SetFocus(Handle);
}
void Disable(){
EnableWindow(Handle, FALSE);
Enabled = false;
}
void Enable(){
EnableWindow(Handle, TRUE);
Enabled = true;
}
void SetText(char* String){
SetWindowTextA(Handle, String);
}
};
class BUTTON : public CONTROL {
public:
BUTTON(int Identifier){
ClassStyle = BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD;
ID = Identifier;
ClassName = "BUTTON";
ExtendedStyle = 0;
}
};
class EDIT : public CONTROL {
public:
EDIT(int Identifier){
ClassStyle = ES_NUMBER | WS_VISIBLE | ES_CENTER | WS_CHILD | ES_NOHIDESEL;
ExtendedStyle = WS_EX_CLIENTEDGE;
ID = Identifier;
ClassName = "EDIT";
}
void Select(int first, int last){
Edit_SetSel(Handle, first, last);
}
int Length(){
return Edit_GetTextLength(Handle);
}
const char* Text(){
char Buffer[Length() + 1];
Edit_GetText(Handle, (LPTSTR)&Buffer, Length() + 1);
string String = Buffer;
return String.c_str();
}
};
class STATIC : public CONTROL {
public:
STATIC() {
ClassStyle = WS_VISIBLE | SS_CENTER | WS_CHILD;
ID = 0;
ClassName = "STATIC";
ExtendedStyle = 0;
}
};
Player You("You"), Dealer("Dealer");
BUTTON Ok(ID_OK), Hit(ID_HIT), Stand(ID_STAND);
EDIT Bet(ID_BET);
STATIC BetLabel, GameControls, PlayerLabels, HandValueLabel, YourMoney, MoneyValue, Bust;
class Game{
public:
bool started;
Game(){
started = false;
}
void Stop(){
started = false;
}
void ResetGame(HWND hWnd){
//Reset Players
You.Reset();
Dealer.Reset();
//Reset Controls
Ok.Enable();
Bet.Enable();
Hit.Enable();
//Reset Hand value
sprintf(Buffer, "%d", You.HandValue());
HandValueLabel.SetText(Buffer);
//Reset deck
deck = Deck();
//Stop the game
started = false;
//Update the Display
InvalidateRect(hWnd, 0, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
}
int SendMessage(HWND hWnd, int ButtonID, unsigned int MESSAGE, int Information, char* _Information){
return ProcessMessage(hWnd, ButtonID, MESSAGE, Information, _Information);
}
int ProcessMessage(HWND hWnd, int ButtonID, unsigned int MESSAGE, int Information, char* _Information){
switch(MESSAGE)
{
case START_GAME:
//Place Bet
You.money -= Information;
started = YES;
sprintf(Buffer, "%d", You.money);
//Update Controls
MoneyValue.SetText(Buffer);
Ok.Disable();
Bet.Disable();
//Deal two cards to player and dealer
You.DealCard();
You.DealCard();
Dealer.DealCard();
Dealer.DealCard();
//Update the Hand Value Label
sprintf(Buffer, "%d", You.HandValue());
HandValueLabel.SetText(Buffer);
//Move the label
MoveWindow(HandValueLabel.Handle, (int)You.x[You.cards] + 80, (int)You.y[You.cards] + 25, 100, 20, TRUE);
//Send PAINT message
InvalidateRect(hWnd,0, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
//Check for BlackJacks
if(You.HandValue() == 21){
SendMessage(hWnd, 0, INTERNAL, YOU_WIN, "");
}
else if(Dealer.HandValue() == 21){
SendMessage(hWnd, 0, INTERNAL, DEALER_WIN, "");
}
break;
case STAND:
if(started){
Hit.Disable();
You.playing = false;
}
break;
case INTERNAL:
switch(Information)
{
case DEALER_WIN:
return MessageBoxA(hWnd, "You Loose! \n Play Again ?", "Game Over", MB_YESNO | MB_ICONINFORMATION);
case YOU_WIN:
return MessageBoxA(hWnd, "You Win! \n Keep Playing ?", "Game Over", MB_YESNO | MB_ICONINFORMATION);
}
break;
case IDLE:
if(started){
//Check for BlackJacks
if(Dealer.HandValue() == 21){
started = false;
switch(SendMessage(hWnd, 0, INTERNAL, DEALER_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
if(!You.playing && Dealer.playing && Dealer.HandValue() < You.HandValue())
Dealer.DealCard();
//Update the Window
InvalidateRect(hWnd,0, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
//Check for a Bust
if(Dealer.HandValue() > 21){
switch(SendMessage(hWnd, 0, INTERNAL, YOU_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
if(Dealer.HandValue() == 21){
switch(SendMessage(hWnd, 0, INTERNAL, YOU_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
}
break;
case HIT:
//Check to see who's still playing and deal a card to them
if(started){
if(You.playing){
You.DealCard();
//Update the Hand Value Label
sprintf(Buffer, "%d", You.HandValue());
HandValueLabel.SetText(Buffer);
//Move the label and update the screen
MoveWindow(HandValueLabel.Handle, (int)You.x[You.cards] + 80, (int)You.y[You.cards] + 25, 100, 20, TRUE);
InvalidateRect(hWnd, 0, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
//Check for a BlackJack
if(You.HandValue() == 21){
started = false;
switch(SendMessage(hWnd, 0, INTERNAL, YOU_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
//Check for a bust
if(You.HandValue() > 21){
started = false;
switch(SendMessage(hWnd, 0, INTERNAL, YOU_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
}
if(Dealer.playing){
Dealer.DealCard();
InvalidateRect(hWnd, 0, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
//Check for BlackJack
if(Dealer.HandValue() == 21){
started = false;
switch(SendMessage(hWnd, 0, INTERNAL, DEALER_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
//Check for Bust
if(Dealer.HandValue() > 21){
started = false;
switch(SendMessage(hWnd, 0, INTERNAL, YOU_WIN, ""))
{
case IDYES:
ResetGame(hWnd);
return 0;
case IDNO:
exit(0);
return 0;
}
}
}
}
break;
}
return 0;
}
};
Game game;
#endif
switch(Msg)
{
case WM_PAINT:
{
PAINTSTRUCT PS;
HDC hDC = BeginPaint(hWnd, &PS);
You.Draw(hDC);
Dealer.Draw(hDC);
EndPaint(hWnd, &PS);
if(Bet.Enabled){
Bet.GetFocus();
Bet.Select(0,Bet.Length());
}
}
return 0;
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC)wParam, TRANSPARENT);
}
return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);
case WM_CREATE:
{
//Create edit control
Bet.Create(hWnd, 10, 550, 100, 25, "0");
//Create labels
char Buffer[30];
sprintf(Buffer, "%d", You.HandValue());
BetLabel.Create(hWnd, 10, 500, 100, 40, "Enter Bet Amount");
GameControls.Create(hWnd, 10, 375, 100, 40, "Game Controls");
PlayerLabels.Create(hWnd, 10, 10, 100, 20, "You:");
PlayerLabels.Create(hWnd, 10, 175, 100, 20, "Dealer:");
HandValueLabel.Create(hWnd, (int)You.x[You.cards] + 85, 60, 100, 20, Buffer);
YourMoney.Create(hWnd, 125, 500, 100, 40, "Your money: ");
sprintf(Buffer, "%d", You.money);
MoneyValue.Create(hWnd, 125, 525, 100, 40, Buffer);
//Create buttons
Ok.Create(hWnd, 10, 600, 100, 50, "Ok");
Hit.Create(hWnd, 10, 425, 100, 50, "Hit");
Stand.Create(hWnd, 120, 425, 100, 50, "Stand");
//Select Text
Bet.Select(0,3);
}
return 0;
case WM_CLOSE:
exit(0);
break;
case WM_COMMAND:
{
switch(HIWORD(wParam))
{
case BN_CLICKED:
{
switch(LOWORD(wParam))
{
case ID_OK:
{
//Place bet
int bet = 0;
bet = StringToNumber(Bet.Text());
game.SendMessage(hWnd, ID_OK, START_GAME, bet, "");
}
break;
case ID_HIT:
{
//Tell the game that the player wants another card
game.SendMessage(hWnd, ID_HIT, HIT, 0, "");
}
break;
case ID_STAND:
game.SendMessage(hWnd, ID_STAND, STAND, 0, "");
}
}
break;
}
}
break;
default:
//Default:
game.SendMessage(hWnd, 0, IDLE, 0, "");
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
return 0;
}