首页 \ 问答 \ HWND动态数组中的相同ID(The same ID in dynamic array of HWND)

HWND动态数组中的相同ID(The same ID in dynamic array of HWND)

我正在学习WinAPI并尝试编写Tic Tac Toe游戏。 我正在使用按钮,其中将显示X,O或空图像。按钮存储在动态数组(HWND)中。为什么所有这些按钮具有相同的ID?

if(GetDlgCtrlID(hBtns[0][0]) == GetDlgCtrlID(hBtns[0][1]))
    MessageBox(hWndDlg,_T("TheSame"),_T(""),NULL);

MessageBox出现了!为什么。 请帮忙。

//KA_SHAG
//Miwa_Mikitin
//XXXOOO
#include<windows.h>
#include<tchar.h>
#include"resource.h"

//Main Proc
BOOL CALLBACK DialogProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam);
//EnumChildProc
BOOL CALLBACK DisableEnableButtons(HWND hwnd,LPARAM lParam);

HWND** hBtns;//Global Dynamic Array of Buttons
int size = 150;//Size of Side of field, Button Size = size/nButtons

//BITMAPS
HBITMAP hBmpX,hBmpO,hBmpNone;
/////////

void CreateButtons(HWND hWndDlg,int nBtnsOld,int nBtnsNew);
void LoadBitmaps();


INT WINAPI WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR cmdLine,INT nShowCmd)
{   
    HWND hWndDlg = CreateDialog(hIns,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DialogProc);

    MSG msg;
    ShowWindow(hWndDlg,1);

    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

BOOL CALLBACK DialogProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
    HINSTANCE hIns = GetModuleHandle(0);            
    static int nBtnsOld = 5;//intitial N of Buttons on a row|col
    static int nBtnsNew;//next update N of Buttons on a row|col
    static BOOL isPlaying = false;
    static BOOL isMyMove = true;

    switch(message)
    {
    case WM_INITDIALOG:
        {       
            LoadBitmaps();
            CreateButtons(hWndDlg,nBtnsOld,nBtnsOld);
        }
        return true;

    case WM_COMMAND:
        if(HIWORD(wParam) == BN_CLICKED)
        {
            //Resize the Button field
            if(LOWORD(wParam) == IDC_BTNSETSIZE)
            {       
                //Determine wich RadioBtn is Checked
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO33))
                    nBtnsNew = 3;//set new nBtns
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO44))
                    nBtnsNew = 4;//set new nBtns
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO55))
                    nBtnsNew = 5;//set new nBtns
                ///////////////////////////////////////////
                //If no difference than ignore
                //else Create new Array of Btns
                if(nBtnsOld != nBtnsNew)
                {
                    CreateButtons(hWndDlg,nBtnsOld,nBtnsNew);
                    nBtnsOld = nBtnsNew;
                }
                /////////////////////////////////////////
                return true;
            }
            if(LOWORD(wParam) == IDC_BTNBEGIN)
            {   
                //Enum Buttons,CheckBox,RadioBtns
                //then Disable or Enable them depending on isPlaying var
                //if TRUE - ENABLE
                //else Disable
                EnumChildWindows(hWndDlg,DisableEnableButtons,isPlaying);
                //switch isPlaying )
                isPlaying = !isPlaying;
                //switch begin Button Text
                if(isPlaying)
                    SetWindowText(GetDlgItem(hWndDlg,IDC_BTNBEGIN),_T("Закінчити гру"));
                else
                    SetWindowText(GetDlgItem(hWndDlg,IDC_BTNBEGIN),_T("Почати гру"));
                /////////////////////////////////////////////////////////////////////
                return true;
            }
            //When Playing
            if(isPlaying)
            {
                //Determine HWND of Pressed Btn
                HWND pressedBtn = GetDlgItem(hWndDlg,LOWORD(wParam));
                HBITMAP propBmp;
                if(isMyMove)
                    propBmp = hBmpX;
                else
                    propBmp = hBmpO;
                //Change BMP
                SendMessage(pressedBtn,
                    BM_SETIMAGE,IMAGE_BITMAP,
                    (LPARAM)propBmp);
                //WHY???
                if(GetDlgCtrlID(hBtns[0][0]) == GetDlgCtrlID(hBtns[0][1]))
                    MessageBox(hWndDlg,_T("TheSame"),_T(""),NULL);

                return true;
            }
        }
        return true;
    case WM_CLOSE:
        DestroyWindow(hWndDlg);
        PostQuitMessage(0);
        return TRUE;
    }

    return FALSE;
}

void CreateButtons(HWND hWndDlg,int nBtnsOld,int nBtnsNew)
{

    HINSTANCE hIns = GetModuleHandle(0);//main instance

    //Destroy Buttons
    if(hBtns)
    {
        for(int i=0;i<nBtnsOld;i++)
            for(int j=0;j<nBtnsOld;j++)
                DestroyWindow(hBtns[i][j]);
        ////////////////////////////////    
        //Free memory
        for(int n=0;n<nBtnsOld;n++)
            delete[]hBtns[n];
        delete[]hBtns;  
    }
    /////////////////////////////////
    //Allocate new memory
    hBtns = new HWND*[nBtnsNew];
    for(int n=0;n<nBtnsNew;n++)
        hBtns[n] = new HWND[nBtnsNew];
    ////////////////////////////////
    int x =0;//offset x
    int y =0;//offset y
    //tchar[] for diff name s of btns

    //Create Buttons & assign to hBtns Array
    for(int i=0;i<nBtnsNew;i++)
    {
        for(int j=0;j<nBtnsNew;j++)
        {

            hBtns[i][j] = CreateWindowEx(
                NULL,_T("Button"),
                NULL,
                WS_CHILD | WS_VISIBLE | BS_BITMAP | BS_NOTIFY ,
                x,y,size/nBtnsNew,size/nBtnsNew,
                hWndDlg,NULL,
                hIns,NULL);
            //Set Default Image On Btns
            SendMessage(hBtns[i][j],BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBmpNone);

            x+=size/nBtnsNew;

        }
        y+=size/nBtnsNew;
        x=0;
    }
}

BOOL CALLBACK DisableEnableButtons(HWND hwnd,LPARAM lParam)
{
    //Lparam is a BOOL if true Button will be Enabled
    //else Buttons will be Disabled
    if( GetDlgCtrlID(hwnd) == IDC_RADIO33 ||
        GetDlgCtrlID(hwnd) == IDC_RADIO44 ||
        GetDlgCtrlID(hwnd) == IDC_RADIO55 ||
        GetDlgCtrlID(hwnd) == IDC_CHECKMOVE ||
        GetDlgCtrlID(hwnd) == IDC_BTNSETSIZE)
        EnableWindow(hwnd,lParam);//<---lParam is BOOL

    return TRUE;
}

//BOOL CALLBACK DrawBmpOnBtn(HWND hwnd,LPARAM lParam)
//{
//
//  SendMessage(hwnd,BM_SETIMAGE,
//  return TRUE;
//}

void LoadBitmaps()
{
    HINSTANCE hIns = GetModuleHandle(0);//main instance

    hBmpX = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_X));
    hBmpO = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_O));
    hBmpNone = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_NONE));
}

项目(VS2008)在这里: http//www.filehosting.org/file/details/372626/XXXOOO.rar

PS执行程序时 - 下方按钮允许绘制蓝色按钮,上方按钮设置蓝色按钮的数量,但检查一些radioBtn。


I'm learning WinAPI and trying to write a Tic Tac Toe game. I`m using buttons in which will be displayed X,O or empty image.Buttons stored in a dynamic array(HWND).Why all this Buttons have the same ID?

if(GetDlgCtrlID(hBtns[0][0]) == GetDlgCtrlID(hBtns[0][1]))
    MessageBox(hWndDlg,_T("TheSame"),_T(""),NULL);

MessageBox appears!, why. Please help.

//KA_SHAG
//Miwa_Mikitin
//XXXOOO
#include<windows.h>
#include<tchar.h>
#include"resource.h"

//Main Proc
BOOL CALLBACK DialogProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam);
//EnumChildProc
BOOL CALLBACK DisableEnableButtons(HWND hwnd,LPARAM lParam);

HWND** hBtns;//Global Dynamic Array of Buttons
int size = 150;//Size of Side of field, Button Size = size/nButtons

//BITMAPS
HBITMAP hBmpX,hBmpO,hBmpNone;
/////////

void CreateButtons(HWND hWndDlg,int nBtnsOld,int nBtnsNew);
void LoadBitmaps();


INT WINAPI WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR cmdLine,INT nShowCmd)
{   
    HWND hWndDlg = CreateDialog(hIns,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DialogProc);

    MSG msg;
    ShowWindow(hWndDlg,1);

    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

BOOL CALLBACK DialogProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
    HINSTANCE hIns = GetModuleHandle(0);            
    static int nBtnsOld = 5;//intitial N of Buttons on a row|col
    static int nBtnsNew;//next update N of Buttons on a row|col
    static BOOL isPlaying = false;
    static BOOL isMyMove = true;

    switch(message)
    {
    case WM_INITDIALOG:
        {       
            LoadBitmaps();
            CreateButtons(hWndDlg,nBtnsOld,nBtnsOld);
        }
        return true;

    case WM_COMMAND:
        if(HIWORD(wParam) == BN_CLICKED)
        {
            //Resize the Button field
            if(LOWORD(wParam) == IDC_BTNSETSIZE)
            {       
                //Determine wich RadioBtn is Checked
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO33))
                    nBtnsNew = 3;//set new nBtns
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO44))
                    nBtnsNew = 4;//set new nBtns
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO55))
                    nBtnsNew = 5;//set new nBtns
                ///////////////////////////////////////////
                //If no difference than ignore
                //else Create new Array of Btns
                if(nBtnsOld != nBtnsNew)
                {
                    CreateButtons(hWndDlg,nBtnsOld,nBtnsNew);
                    nBtnsOld = nBtnsNew;
                }
                /////////////////////////////////////////
                return true;
            }
            if(LOWORD(wParam) == IDC_BTNBEGIN)
            {   
                //Enum Buttons,CheckBox,RadioBtns
                //then Disable or Enable them depending on isPlaying var
                //if TRUE - ENABLE
                //else Disable
                EnumChildWindows(hWndDlg,DisableEnableButtons,isPlaying);
                //switch isPlaying )
                isPlaying = !isPlaying;
                //switch begin Button Text
                if(isPlaying)
                    SetWindowText(GetDlgItem(hWndDlg,IDC_BTNBEGIN),_T("Закінчити гру"));
                else
                    SetWindowText(GetDlgItem(hWndDlg,IDC_BTNBEGIN),_T("Почати гру"));
                /////////////////////////////////////////////////////////////////////
                return true;
            }
            //When Playing
            if(isPlaying)
            {
                //Determine HWND of Pressed Btn
                HWND pressedBtn = GetDlgItem(hWndDlg,LOWORD(wParam));
                HBITMAP propBmp;
                if(isMyMove)
                    propBmp = hBmpX;
                else
                    propBmp = hBmpO;
                //Change BMP
                SendMessage(pressedBtn,
                    BM_SETIMAGE,IMAGE_BITMAP,
                    (LPARAM)propBmp);
                //WHY???
                if(GetDlgCtrlID(hBtns[0][0]) == GetDlgCtrlID(hBtns[0][1]))
                    MessageBox(hWndDlg,_T("TheSame"),_T(""),NULL);

                return true;
            }
        }
        return true;
    case WM_CLOSE:
        DestroyWindow(hWndDlg);
        PostQuitMessage(0);
        return TRUE;
    }

    return FALSE;
}

void CreateButtons(HWND hWndDlg,int nBtnsOld,int nBtnsNew)
{

    HINSTANCE hIns = GetModuleHandle(0);//main instance

    //Destroy Buttons
    if(hBtns)
    {
        for(int i=0;i<nBtnsOld;i++)
            for(int j=0;j<nBtnsOld;j++)
                DestroyWindow(hBtns[i][j]);
        ////////////////////////////////    
        //Free memory
        for(int n=0;n<nBtnsOld;n++)
            delete[]hBtns[n];
        delete[]hBtns;  
    }
    /////////////////////////////////
    //Allocate new memory
    hBtns = new HWND*[nBtnsNew];
    for(int n=0;n<nBtnsNew;n++)
        hBtns[n] = new HWND[nBtnsNew];
    ////////////////////////////////
    int x =0;//offset x
    int y =0;//offset y
    //tchar[] for diff name s of btns

    //Create Buttons & assign to hBtns Array
    for(int i=0;i<nBtnsNew;i++)
    {
        for(int j=0;j<nBtnsNew;j++)
        {

            hBtns[i][j] = CreateWindowEx(
                NULL,_T("Button"),
                NULL,
                WS_CHILD | WS_VISIBLE | BS_BITMAP | BS_NOTIFY ,
                x,y,size/nBtnsNew,size/nBtnsNew,
                hWndDlg,NULL,
                hIns,NULL);
            //Set Default Image On Btns
            SendMessage(hBtns[i][j],BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBmpNone);

            x+=size/nBtnsNew;

        }
        y+=size/nBtnsNew;
        x=0;
    }
}

BOOL CALLBACK DisableEnableButtons(HWND hwnd,LPARAM lParam)
{
    //Lparam is a BOOL if true Button will be Enabled
    //else Buttons will be Disabled
    if( GetDlgCtrlID(hwnd) == IDC_RADIO33 ||
        GetDlgCtrlID(hwnd) == IDC_RADIO44 ||
        GetDlgCtrlID(hwnd) == IDC_RADIO55 ||
        GetDlgCtrlID(hwnd) == IDC_CHECKMOVE ||
        GetDlgCtrlID(hwnd) == IDC_BTNSETSIZE)
        EnableWindow(hwnd,lParam);//<---lParam is BOOL

    return TRUE;
}

//BOOL CALLBACK DrawBmpOnBtn(HWND hwnd,LPARAM lParam)
//{
//
//  SendMessage(hwnd,BM_SETIMAGE,
//  return TRUE;
//}

void LoadBitmaps()
{
    HINSTANCE hIns = GetModuleHandle(0);//main instance

    hBmpX = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_X));
    hBmpO = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_O));
    hBmpNone = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_NONE));
}

The Project(VS2008) is here : http://www.filehosting.org/file/details/372626/XXXOOO.rar

P.S.when execute the program - lower Button allow to draw in a blue buttons,upper button set the amount of blue buttons, but check some radioBtn.


原文:https://stackoverflow.com/questions/12285945
更新时间:2023-12-06 16:12

最满意答案

正如@Michael - sqlbot提到的,你没有使用由assume_role API调用生成的标记。 使用获取的凭证创建您的EC2客户端对象。 用get_sts_token(RoleArn=role_arn, RegionName="us-east-1")替换get_sts_token(RoleArn=role_arn, RegionName="us-east-1")行,以检索临时凭证并使用它来列出实例:

credentials = get_sts_token(RoleArn=role_arn, RegionName="us-east-1")
access_key = credentials['AccessKeyId']
secret_key = credentials['SecretAccessKey']
token = credentials['SessionToken']
session = boto3.session.Session(
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key,
    aws_session_token=token
)
client = session.client('ec2', region_name='us-east-1')
response = client.describe_instances()
print(response)

这将返回我们所有的实例 - east-1。 如果您需要所有地区的实例列表,请调用describe_regions API并遍历列表。

参考文献:

  • 关于Session对象的文档可以在这里找到。

As @Michael - sqlbot mentioned, you are not using the token generated by the assume_role API call. Create your EC2 client object using the credentials obtained. Replace get_sts_token(RoleArn=role_arn, RegionName="us-east-1") line in your code with the following lines to retrieve the temporary credentials and use it to list the instances:

credentials = get_sts_token(RoleArn=role_arn, RegionName="us-east-1")
access_key = credentials['AccessKeyId']
secret_key = credentials['SecretAccessKey']
token = credentials['SessionToken']
session = boto3.session.Session(
    aws_access_key_id=access_key,
    aws_secret_access_key=secret_key,
    aws_session_token=token
)
client = session.client('ec2', region_name='us-east-1')
response = client.describe_instances()
print(response)

This will return all the instances in us-east-1. If you need the list of instances in all regions, call describe_regions API and iterate through the list.

References:

  • Documentation about Session object can be found here.

相关问答

更多
  • 您可以设置UserData并启动实例,它将获取更改: http : //boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.modify_instance_attribute 但是,UserData脚本通常只设置为运行一次,因此您必须修改它以在每次启动时运行: 如何在每次启动EC2实例时运行cloud-init启动脚本? 另一种方法是在启动后设置SSH并运行脚本,但在我看来,在UserData中推荐使用更简洁。 I wa ...
  • 适用于.Net的AWS开发工具包具有AmazonSimpleSystemsManagementClient 。 在客户端上调用SendCommand()方法 。 The AWS SDK for .Net has a AmazonSimpleSystemsManagementClient. Call the SendCommand() method on the client.
  • 我已将上述语句从./test.sh为screen -d -m ./test.sh ,它对我screen -d -m ./test.sh 。 I have changed the above statement from ./test.sh to screen -d -m ./test.sh and it did the trick for me.
  • 如果您正在实例上运行脚本,则可以从ECS代理的introspection API中找到容器实例ID。 如果您从ECS任务中运行脚本,则可以使用容器元数据文件 。 If you're running a script on the instance, you can find the container instance ID from the ECS agent's introspection API. If you're running a script from within an ECS task, ...
  • 正如@Michael - sqlbot提到的,你没有使用由assume_role API调用生成的标记。 使用获取的凭证创建您的EC2客户端对象。 用get_sts_token(RoleArn=role_arn, RegionName="us-east-1")替换get_sts_token(RoleArn=role_arn, RegionName="us-east-1")行,以检索临时凭证并使用它来列出实例: credentials = get_sts_token(RoleArn=role_arn, Reg ...
  • 启动临时实例时,请指定 --instance-initiated-shutdown-behavior terminate 然后,当实例完成其所有任务时,只需运行等效的 sudo halt 要么 sudo shutdown -h now 使用上面的标志,这将告诉实例从实例内部关闭应终止实例(而不是仅停止它)。 When you start the temporary instance, specify --instance-initiated-shutdown-behavior terminate T ...
  • 您的EB应用程序正在使用Auto Scaling组来确保您的EC2实例保持运行。 当您停止EC2实例时,Auto Scaling会将其视为不健康的实例并终止它,然后将其替换为新的健康实例。 您无法停止属于Auto Scaling组的EC2实例。 您可以做的最好的方法是编辑您的Auto Scaling组策略,以设置min=desired=0 。 这将终止实例并保持它终止。 当您想让实例再次运行时,编辑您的Auto Scaling组并重置min=desired=1 。 Your EB application i ...
  • 通过一个简单的二元运算符进行混淆看起来有点愚蠢,因为它看起来工作起来很少,以防止人们搞清楚。 我认为罗森先生偶然发现了一种可能的用途,我能想到的唯一的办法就是某种形式的资源跟踪。 当然,直到亚马逊的一位人士告诉我们,这将会是纯粹闲散的猜测。 Obfuscation via a straightforward binary operator seems a little silly considering how little it apparently worked to prevent people fr ...
  • 对于处理amazon实例,您可能希望使用boto ,它提供了大多数常用功能。 阅读文档非常重要,因为数据丢失是一种可能性。 考虑从这里开始。 要计算实例运行多长时间,可以使用instance.launch_time 。 要停止实例,可以使用instance.stop : 停止Amazon EBS支持的实例。 每次将实例从停止转换为启动时,即使转换在一小时内发生多次,Amazon EC2也会收取完整的实例小时数。 您无法启动或停止竞价型实例。 (更多链接...) 要终止实例,请使用instance.termi ...
  • 不,你不能将输出设置为ips。 云形成负责自动缩放组和自动缩放启动配置,但它无法控制各个EC2实例,因此您无法从它们获取信息到输出中。 您可以在启动时编写在EC2实例上运行的内容,以使用ip值在堆栈上设置标记。 但是当实例终止时,这可能很难维护。 No you can't set the outputs to be the ips. The cloud formation is responsible for the autoscaling groups and the autoscaling launch ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)